Knowledge/Python

[코드트리] 가운데에서 시작하여 빙빙 돌기 ,python 문제 풀이

발달중인 망고 2022. 7. 17. 17:06

안녕하세요, 오늘은 dx, dy테크닉에 관련하여 새로운 문제를 소개해드리겠습니다.


문제

n * n크기의 직사각형의 가운데에서 시작하여 오른쪽, 위, 왼쪽, 아래 순서로 더 이상 채울 곳이 없을 때까지 회전하며 숫자를 적어나가려고 합니다. 숫자는 1부터 시작한다고 했을 때, 다음과 같은 모양으로 숫자들을 쭉 채우는 코드를 작성해보세요.

입력 형식

첫 번째 줄에 크기를 나타내는 n이 주어집니다. 주어지는 n은 항상 홀수라고 가정해도 좋습니다.

  • 1 ≤ n ≤ 100

출력 형식

숫자로 채워진 완성된 형태의 n * n 크기의 사각형을 출력합니다.
(숫자끼리는 공백을 사이에 두고 출력합니다.)

입출력 예제

예제 1

입력:

3
 

출력:

5 4 3
6 1 2
7 8 9
 

예제 2

입력:

5
 

출력:

17 16 15 14 13
18 5 4 3 12
19 6 1 2 11
20 7 8 9 10
21 22 23 24 25
 

제한

시간 제한: 1000ms
메모리 제한: 80MB

 


코드

#              1
#              ^
#              |      
#      2 <-- (/,\) --> 0 
#              | 
#              v
#              3

n = int(input())

def in_range(x, y):
    return 0 <= x and x < n and 0 <= y and y <n

def move(dir_now):
    if dir_now == 0:
        return [0, 1]
    elif dir_now == 1:
        return [-1, 0]
    elif dir_now == 2:
        return [0, -1]
    else:
        return [1, 0]

array = [[0 for i in range(n)]for j in range(n)] 

dir_state = 3

step = 1

#왼쪽에 머가 없다면 돈다.

x , y = (n-1)//2 , (n-1)//2

i = 0

array[x][y]=1

while True:
    #좌측 검사 포지션
    dir_state_left = dir_state + 1
    ldx, ldy = move(dir_state_left % 4)
    lx , ly = x + ldx , y + ldy
    #
    if n != 1 and array[lx][ly] == 0:
        dir_state += 1

    dx, dy = move(dir_state % 4)

    if in_range( x + dx ,y + dy) == True and array[x+dx][y+dy] == 0:
        # 가는 방향이 맞고 0으로 돼있다면 진행한다
        # 추가적으로 왼쪽에 숫자가 없다면 방향을 
        x , y = x + dx , y + dy
        step += 1

    array[x][y] = step
    if step >= n*n:
        break


    
for i in range(n):
    for j in range(n):
        print(array[i][j],end=" ")
    print()

이 문제에 관하여 여러 문제 풀이가 있을 수 있겠지만 저는 직관적으로 더 이해하기 쉬운 "왼쪽에 숫자가 없다면 방향을 바꾼다"라는 알고리즘을 사용하게 되었습니다. 밧줄을 감을 때도 구심점이 되는 물체가 없다면 한 방향으로 감듯이 왼쪽에 기댈 물체가 없다면 방향을 진행방향에서 왼쪽으로 꺾어주는 느낌입니다. 코드를 읽어보시면 이해하기 쉬우실 것입니다. 파이썬이 처음이라 지적, 조언 감사히 받겠습니다~