[백준] #1913 달팽이(python)

수영·2022년 8월 14일

백준

목록 보기
35/117
post-thumbnail

📌문제

홀수인 자연수 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

백준 1913번 문제

💡Idea

표를 잘 보다보면, 규칙을 하나 발견할 수 있습니다🧐

  1. 좌표는 위, 오른쪽, 아래, 왼쪽 순서를 반복하며 이동한다.
  2. 좌표는 1, 1, 2, 2, 3, 3... 의 순서만큼씩 이동한다.
  3. NN이 홀수이므로 항상 좌표는 위로 올라가는 순서에서 끝난다. 이 때, 바로 직전의 좌표가 이동한 만큼만 이동한다.
    (아래 사진에서 5만큼 이동할 차례이지만, 4만큼만 이동)

따라서 위와 같은 규칙을 가지고 이동하는 좌표를 구현해주면 됩니다.

💻코드

  • ⏰ 시간 : 1148 ms / 메모리 : 70192 KB
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의 좌표 출력

📝코드 설명

좌표가 이동하는 규칙을 그대로 구현한 코드입니다.

xy는 표의 인덱스로써, 1의 값이 들어가야하는 (N // 2, N // 2)부터 시작하여 좌표 이동의 규칙대로 이동합니다.

while 문 안에서는 위, 오른쪽, 아래, 왼쪽 순서대로 한 번씩 이동합니다.

좌표를 이동하면서 i의 값을 1부터 시작하여 1씩 증가시키면서 answer에 값을 넣어줍니다. (k의 값이 1씩 증가하기 때문에, i의 값에 k를 더해주고, 다음 for문으로 넘어갈 때는 ik를 더해주어 그 다음 수를 이어 넣어줄 수 있도록 합니다. )

동일한 방향으로 이동하는 횟수는 j에 따라 달라지는데, 위, 오른쪽, 아래, 왼쪽의 방향으로 한 번 돌고 나면 j의 값을 2씩 증가시켜주었습니다.

계속해서 좌표를 이동시키면서 표를 채워가다가, 위로 올라가는 순서에서 j의 값이 표의 크기인 N 보다 커지면 더이상 진행하지 않고 종료할 수 있도록 해주었습니다.

profile
하고 싶은 건 그냥 죽도록 합니다

0개의 댓글