1780

https://www.acmicpc.net/problem/1780

import sys
input = sys.stdin.readline

n = int(input())
paper = [list(map(int, input().split())) for _ in range(n)]
cnt = [0]*3

def ans(l, x, y):
    tmp = paper[x][y]
    for i in range(x,x+l):
        for j in range(y,y+l):
            if tmp != paper[i][j]:
                for a in range(3):
                    for b in range(3):
                        ans(l//3,x + a*(l//3),y + b*(l//3))
                return
    cnt[tmp+1] += 1

ans(n, 0, 0)
print(*cnt, sep = "\n")

point 1

사실 모든 수가 같은 지만 판단하도록 함수를 작성한 후 매개변수를 9분할 구간을 판단할 수록 설정하여 구간마다 재귀를 돌리는 것이 훨씬 시간은 빠를 것 같다. 하지만 긴 코드를 작성하는 것이 귀찮았으므로 ,,, 한 번의 재귀호출로 (코드 상 1번) 처리할 수 있도록 일반화했다.

soltion

paper[x][y]를 기준으로, 주어진 구간의 값이 같지 않다면, 각 구간이 모두 같은 수로 채워질 때까지 9개로 구간을 분할하도록 했다. 주어진 값이 0, 1, -1이므로, cnt 배열의 값을 늘려줄 때 각각의 값을 인덱스로 사용해도 문제가 발생하지 않으나, 출력부를 작성할 때 반복문의 범위를 (-1,2)로 설정해주어야하는 불편함이 있어 cnt 배열에 개수를 저장할 때 tmp+1인 인덱스의 값을 증가시켰다.

4779

https://www.acmicpc.net/problem/4779

import sys
input = sys.stdin.readline

def div(n, li):
    if n == 1: return li
    l = n//3
    return div(l,li[:l]) + " "*l + div(l, li[l*2:])

while True:
    n = input().rstrip()
    if n == "": break
    num = 3**int(n); dash = "-"*num
    print(div(num,dash))

1074

https://www.acmicpc.net/problem/1074

def div(size, row, col, cnt):
    l = size//2
    if r == row and c == col: print(cnt)
    elif r < row + l and c < col + l: div(l, row, col, cnt)
    elif r < row + l and c >= col + l: div(l, row, col + l, cnt + l**2)
    elif r >= row + l and c < col + l: div(l, row + l, col, cnt + (l**2) * 2)
    elif r >= row + l and c >= col + l: div(l, row + l, col + l, cnt + (l ** 2) * 3)

n, r, c = map(int, input().split())
div(2**n, 0, 0, 0)

2447

https://www.acmicpc.net/problem/2447

def star(n):
    if n == 1: return ['*']
    
    rec = star(n//3); ans = []
    for i in rec: ans.append(i*3)
    for i in rec: ans.append(i + ' '*(n//3) + i)
    for i in rec: ans.append(i*3)

    return ans

# print(*star(int(input())), sep = "\n")
print('\n'.join(star(int(input()))))

soltion

구조는 알겠으나 어떻게 재귀로 구현해야할 지 떠올리기 힘들었던 문제. 비어있는 곳의 점화식을 구해 3*3의 별을 채워야하는 곳에 넣어야한다는 생각에서 벗어나는 데에 시간이 오래 걸렸다. n을 3씩 나눠가며 n==1일 될 때까지 재귀를 돌면 필요한만큼 재귀를 돌 수 있다. 이 때 기존에 생성된 rec(초기에는 * 하나)을 모든 구역에 3배로 채워넣으며, 가운데 영역만 비워둘 수 있도록 했다.
*를 사용한 출력이 익숙하여 위 코드에서 주석처리된 출력문을 사용했는데, join을 사용하는 것이 시간이 더 빠르다. join을 사용하는 데에 익숙해져야겠다