본문 바로가기
Algorithm/Python

백준 1913번 달팽이

by Shark_상어 2023. 1. 12.
728x90

1. 문제 설명

문제 링크

홀수인 자연수 N이 주어지면, 다음과 같이 1부터 N2까지의 자연수를 달팽이 모양으로 N×N의 표에 채울 수 있다.

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

N이 주어졌을 때, 이러한 표를 출력하는 프로그램을 작성하시오. 또한 N2 이하의 자연수가 하나 주어졌을 때, 그 좌표도 함께 출력하시오. 예를 들어 N=5인 경우 6의 좌표는 (4,3)이다.

  • 입력
    • 첫째 줄에 홀수인 자연수 N(3 ≤ N ≤ 999)이 주어진다. 둘째 줄에는 위치를 찾고자 하는 N2 이하의 자연수가 하나 주어진다.
  • 출력
    • N개의 줄에 걸쳐 표를 출력한다. 각 줄에 N개의 자연수를 한 칸씩 띄어서 출력하면 되며, 자릿수를 맞출 필요가 없다. N+1번째 줄에는 입력받은 자연수의 좌표를 나타내는 두 정수를 한 칸 띄어서 출력한다..

2. 코드

import sys

input = sys.stdin.readline

# 아래, 오른쪽, 위로, 왼쪽 순서
dx = [1, 0, -1, 0]
dy = [0, 1, 0, -1]

# 입력
n = int(input())

# 찾는 수 입력
f_n = int(input())

# 달팽이 를 구현 하기 위한 이중배열
arr = [[0] * n for _ in range(n)]


# 방향성의 규칙에 의한 -1 선언
d = -1

# n * n 의 값부터 시작!
k = n * n

# 0,0 이 아닌 -1, 0 으로 배정이후 규칙성에 넣기
x, y = -1, 0

# 찾는 숫자 값 넣기 위한 배열
ans = []

# 모든 달팽이는 n * 2 - 1 횟수 안에 다 끝난다.
for _ in range(n * 2 - 1):
    # 방향
    d = (d + 1) % 4

    # n번 만큼 움직인다.
    for _ in range(n):

        # 규칙성에 의해 값 플러스 하기
        x += dx[d]
        y += dy[d]

        # 해당 위치 k값으로 정의
        arr[x][y] = k

        # 만약 k가 찾는 수라면
        if k == f_n:
            # 배열에 넣기
            ans.append((x + 1, y + 1))
        # k -= 1 진행하므로 달팽이 움직임을 보여주기
        k -= 1
    # 만약 아래로 내려가는 것 또는 위로 올라 가는 것이 끝났다면 n을 -1 더해서 n번 을 줄이기
    if not d or not d % 2:
        n -= 1
# 반복문을 이용하여 해당 인덱스 값을 Unpacking 통해 출력
for i in range(len(arr)): print(*arr[i])

# 위치값 Unpacking으로 출력하기
print(*ans[0])

3. 회고

Q. 문제를 보고 든 생각

  • 달팽이의 이동 순서
    • 안쪽의 1부터 보단 좌표(0, 0) 부터 큰 값으로 아래, 오른쪽, 위, 왼쪽 순서로 돌리면 될것 같다는 생각을 했었다.
  • 규칙성
    • 해당 문제는 아래 또는 위 이라는 이동이 끝나면 넣어 갈 숫자의 갯수가 줄어든다.
    • 이를 이용해 n 값을 기준으로 반복문을 돌려 실행 하면 범위도 벗어나지않으며 원래 넣었던 값도 손실되지 않는다.

4. 고쳐야 할점

조금 더 줄여서 파이썬 답게 구현 할수 있을 것같은데 잘 떠오르지 않아서... 좋은 방안 있으면 댓글로 알려주세요!

728x90

'Algorithm > Python' 카테고리의 다른 글

백준 2636번 치즈  (0) 2023.01.18
백준 1990번 소수인팰린드롬  (0) 2023.01.15
백준 17135번 캐슬 디펜스  (1) 2023.01.09
백준 9613번 GCD 합  (0) 2023.01.08
백준 17103번 골드바흐 파티션  (0) 2023.01.08