홀수인 자연수 N이 주어지면, 다음과 같이 1부터 N2까지의 자연수를 달팽이 모양으로 N×N의 표에 채울 수 있다.
N이 주어졌을 때, 이러한 표를 출력하는 프로그램을 작성하시오. 또한 N2 이하의 자연수가 하나 주어졌을 때, 그 좌표도 함께 출력하시오. 예를 들어 N=5인 경우 6의 좌표는 (4,3)이다.
첫째 줄에 홀수인 자연수 N(3 ≤ N ≤ 999)이 주어진다. 둘째 줄에는 위치를 찾고자 하는 N2 이하의 자연수가 하나 주어진다.
N개의 줄에 걸쳐 표를 출력한다. 각 줄에 N개의 자연수를 한 칸씩 띄어서 출력하면 되며, 자릿수를 맞출 필요가 없다. N+1번째 줄에는 입력받은 자연수의 좌표를 나타내는 두 정수를 한 칸 띄어서 출력한다.
7
35
49 26 27 28 29 30 31
48 25 10 11 12 13 32
47 24 9 2 3 14 33
46 23 8 1 4 15 34
45 22 7 6 5 16 35
44 21 20 19 18 17 36
43 42 41 40 39 38 37
5 7
표를 잘 보다보면, 규칙을 하나 발견할 수 있습니다🧐
- 좌표는 위, 오른쪽, 아래, 왼쪽 순서를 반복하며 이동한다.
- 좌표는 1, 1, 2, 2, 3, 3... 의 순서만큼씩 이동한다.
- 이 홀수이므로 항상 좌표는 위로 올라가는 순서에서 끝난다. 이 때, 바로 직전의 좌표가 이동한 만큼만 이동한다.
(아래 사진에서 5만큼 이동할 차례이지만, 4만큼만 이동)
따라서 위와 같은 규칙을 가지고 이동하는 좌표를 구현해주면 됩니다.
import sys
input = sys.stdin.readline
N = int(input()) # 표의 크기 N
n = int(input()) # 좌표를 찾아야 하는 숫자
answer = [[1 for _ in range(N)] for _ in range(N)] # NxN 표를 1로 초기화
x = y = N // 2 # x좌표와 y좌표
i = j = 1 # i는 표에 들어가는 숫자로 1부터 1씩 증가 / j는 좌표의 이동양
while True:
for k in range(1, min(N, j + 1)): # 가장 마지막 좌표의 이동인 경우 N만큼만 이동
x -= 1 # 좌표가 min(N, j+1)만큼 위로 이동
answer[x][y] = i + k # 위로 이동하면서 1씩 증가된 수 저장
i += k
if j >= N: # 종료 조건
break
for k in range(1, j + 1):
y += 1 # 좌표가 j만큼 오른쪽으로 이동
answer[x][y] = i + k # 오른쪽으로 이동하면서 1씩 증가된 수 저장
i += k
for k in range(1, j + 2):
x += 1 # 좌표가 j+1만큼 아래로 이동
answer[x][y] = i + k # 아래로 이동하면서 1씩 증가된 수 저장
i += k
for k in range(1, j + 2):
y -= 1 # 좌표가 j+1만큼 왼쪽으로 이동
answer[x][y] = i + k # 왼쪽으로 이동하면서 1씩 증가된 수 저장
i += k
j += 2
a = b = 0 # n의 x, y 좌표
for i in range(N):
for j in range(N):
print(answer[i][j], end=' ') # 표 한 줄씩 출력
if answer[i][j] == n: # n을 찾으면 해당 좌표 a와 b에 저장
a = i+1
b = j+1
print()
print(a, b) # n의 좌표 출력
좌표가 이동하는 규칙을 그대로 구현한 코드입니다.
x와 y는 표의 인덱스로써, 1의 값이 들어가야하는 (N // 2, N // 2)부터 시작하여 좌표 이동의 규칙대로 이동합니다.
while 문 안에서는 위, 오른쪽, 아래, 왼쪽 순서대로 한 번씩 이동합니다.
좌표를 이동하면서 i의 값을 1부터 시작하여 1씩 증가시키면서 answer에 값을 넣어줍니다. (k의 값이 1씩 증가하기 때문에, i의 값에 k를 더해주고, 다음 for문으로 넘어갈 때는 i에 k를 더해주어 그 다음 수를 이어 넣어줄 수 있도록 합니다. )
동일한 방향으로 이동하는 횟수는 j에 따라 달라지는데, 위, 오른쪽, 아래, 왼쪽의 방향으로 한 번 돌고 나면 j의 값을 2씩 증가시켜주었습니다.
계속해서 좌표를 이동시키면서 표를 채워가다가, 위로 올라가는 순서에서 j의 값이 표의 크기인 N 보다 커지면 더이상 진행하지 않고 종료할 수 있도록 해주었습니다.