728x90
728x90
문제
달팽이는 1부터 N*N까지의 숫자가 시계방향으로 이루어져 있다.
다음과 같이 정수 N을 입력 받아 N크기의 달팽이를 출력하시오.
예제
N이 3일 경우,
N이 4일 경우,
제약 사항
달팽이의 크기 N은 1 이상 10 이하의 정수이다. (1 ≤ N ≤ 10)
입력
가장 첫 줄에는 테스트 케이스의 개수 T가 주어지고, 그 아래로 각 테스트 케이스가 주어진다.
각 테스트 케이스에는 N이 주어진다.
출력
각 줄은 '#t'로 시작하고, 다음 줄부터 빈칸을 사이에 두고 달팽이 숫자를 출력한다.
(t는 테스트 케이스의 번호를 의미하며 1부터 시작한다.)
예제
[입력] | [출력] |
2 3 4 |
#1 1 2 3 8 9 4 7 6 5 #2 1 2 3 4 12 13 14 5 11 16 15 6 10 9 8 7 |
문제 해결 방법
- 2차원 리스트를 만든 후, 규칙을 찾아 방향을 바꾸며 숫자를 채워넣는 문제이다.
- 우선 @0@으로 채워진 N × N 크기의 2차원 리스트를 생성한다.
matrix = [[0] * N for _ in range(N)]
- 그리고 방향의 변화를 나타내기 위한 리스트 2개(x축 방향(@dir_x@), y축 방향(@dir_y@))를 생성해준다.
# x좌표와 y좌표를 이동하기 위한 방향 설정 (오른쪽, 아래쪽, 왼쪽, 위쪽)
dir_x = [1, 0, -1, 0] # x축 방향
dir_y = [0, 1, 0, -1] # y축 방향
- 예를 들어, 아래와 같이 오른쪽 → 아래쪽 → 왼쪽 → 위쪽으로 이동할 경우, @M[y][x]@에서 @x@의 변화를 확인해보면 오른쪽으로 이동할 때 @+1@, 아래쪽으로 이동할 때 @+0@, 왼쪽으로 이동할 때 @-1@, 위쪽으로 이동할 때 @+0@임을 확인할 수 있다.
- 또한 @y@의 변화를 확인해보면 오른쪽으로 이동할 때 @+0@, 아래쪽으로 이동할 때 @+1@, 왼쪽으로 이동할 때 @+0@, 위쪽으로 이동할 때 @-1@임을 확인할 수 있다.
x↑ (+0) | y↑ (-1) | |||
M[0][0] | M[0][1] | M[0][2] | x→ (+1) | |
y← (+0) | M[1][0] | M[1][1] | M[1][2] | y→ (+0) |
x← (-1) | M[2][0] | M[2][1] | M[2][2] | |
y↓ (+1) | x↓ (+0) |
- 초기 위치와 방향을 설정해준다.
- @x@와 @y@는 2차원 리스트의 인덱스 값을 의미한다.
- @dir@은 1차원 리스트의 인덱스 값을 의미한다.
# 초기 위치와 방향 설정하기
x = 0
y = 0
dir = 0
- 본격적으로 알고리즘을 작성하도록 한다.
- @matrix[y][x]@에는 @1@부터 @N@까지의 숫자가 각각 넣어지도록 한다.
- 여기에서 2차원 리스트의 인덱스 값인 @x@와 @y@ 값에 변화를 줌으로써, 달팽이 모양으로 숫자가 담기도록 해줄 것이다.
matrix[y][x] = num
- for 문을 한 번 작업할 때마다(한 스텝이 끝날 때마다) 다음의 x좌표(@next_x@)와 y좌표(@next_y@)를 설정해주어야 한다.
next_x = x + dir_x[dir]
next_y = y + dir_y[dir]
- @x@ 좌표와 @y@ 좌표가 업데이트 될 수 있도록 한다.
- 만약 한 스텝을 마친 후, 다음의 x좌표(@next_x@)와 y좌표(@next_y@)가 N × N 리스트 안에 있고, 해당 위치에 있는 리스트 안의 값이 @0@일 경우, 다음 스텝의 2차원 리스트의 x 좌표와 y 좌표를 각각 위에서 계산한 다음 좌표로 설정한다. (@x, y = next_x, next_y@)
- 만약 다음의 x좌표(@next_x@)와 y좌표(@next_y@)가 N × N 리스트 밖에 있게될 경우 방향(@dir@)을 바꿔줘야 한다.
- 오른쪽 → 아래쪽 → 왼쪽 → 위쪽 순서로 방향이 바뀌므로 위에서 미리 생성한 @dir_x@ 리스트와 @dir_y@ 리스트를 활용하여 방향을 바꿔준다.
- 방향(@dir@)은 상/하/좌/우 4개(인덱스 @0@부터 @3@까지)만 나오도록 @%@ 연산자를 사용하여 반복되도록 한다.
# x, y 좌표 업데이트
if 0 <= next_x < N and 0 <= next_y < N and matrix[next_y][next_x] == 0: # 범위 안에 있을 경우
x = next_x
y = next_y
else: # 범위 밖에 있을 경우
dir = (dir + 1) % 4
x = x + dir_x[dir]
y = y + dir_y[dir]
코드
def solution(N):
# 0으로 채워진 N x N 크기의 배열 생성
matrix = [[0] * N for _ in range(N)]
# x좌표와 y좌표를 이동하기 위한 방향 설정 (오른쪽, 아래쪽, 왼쪽, 위쪽)
dir_x = [1, 0, -1, 0] # x축 방향
dir_y = [0, 1, 0, -1] # y축 방향
# 초기 위치와 방향 설정하기
x = 0
y = 0
dir = 0
for num in range(1, (N * N) + 1):
matrix[y][x] = num
next_x = x + dir_x[dir]
next_y = y + dir_y[dir]
# x, y 좌표 업데이트
if 0 <= next_x < N and 0 <= next_y < N and matrix[next_y][next_x] == 0: # 범위 안에 있을 경우
x = next_x
y = next_y
else: # 범위 밖에 있을 경우
dir = (dir + 1) % 4
x = x + dir_x[dir]
y = y + dir_y[dir]
return matrix
T = int(input())
for test_case in range(1, T + 1):
N = int(input())
matrix = solution(N)
print(f"#{test_case}")
for row in matrix:
print(" ".join(map(str, row)))
참고
- 난이도: D2
728x90
728x90
'Problem Solving > SWEA' 카테고리의 다른 글
[SWEA-1940][Python] 가랏! RC카! (1) | 2023.10.19 |
---|---|
[SWEA-1945][Python] 간단한 소인수분해 (1) | 2023.10.19 |
[SWEA-1946][Python] 간단한 압축 풀기 (1) | 2023.10.19 |
[SWEA-1948][Python] 날짜 계산기 (1) | 2023.10.19 |
[SWEA-1959][Python] 두 개의 숫자열 (0) | 2023.10.17 |
[SWEA-1961][Python] 숫자 배열 회전 (0) | 2023.10.17 |
[SWEA-1966][Python] 숫자를 정렬하자 (1) | 2023.10.16 |
[SWEA-1970][Python] 쉬운 거스름돈 (0) | 2023.10.16 |