https://www.acmicpc.net/problem/1022
1022번: 소용돌이 예쁘게 출력하기
첫째 줄에 네 정수 r1, c1, r2, c2가 주어진다.
www.acmicpc.net
1. 문제 이해
1이 위치하는 좌표를 (0, 0)이라고 했을 때 밑 사진과 같이 반시계로 소용돌이 모양으로 숫자를 채워나갈 때 (r1,c1) ~ (r2, c2)까지 범위의 숫자들을 '예쁘게' 출력하면 됩니다.
2. 문제 접근
1을 시작으로 오른쪽 아래의 숫자들의 증가폭이 8, 16, 24가 됨을 알 수 있었습니다. 이를 활용하여 사각형의 테두리에서 가장 큰 숫자를 얻을 수 있습니다. 그리고 각 숫자들은 행과 열의 값 중 절대값이 더 큰 값을 n이라고 했을 때 n + 1번째 사각형에 속하게 됩니다.
예를 들어 34는 (-3, 0)이므로 4번째 사각형에 속하게 됩니다. 현재까지 (r, c)가 주어졌을 때 몇번째 사각형에 속해있고 해당 사각형에서 가장 큰 숫자가 무엇인지 알게 되었습니다. 이를 활용하여 (r, c)에 어떤 숫자가 있는지 알아낼 수 있습니다. 각각의 사각형은 4개의 변으로 이루어져 있습니다. 현재가 n번째 사각형이라고 했을 때 밑변은 행이 n - 1, 왼쪽변은 열이 -(n - 1), 윗변은 행이 -(n - 1), 오른쪽 변은 열이 n - 1값을 갖습니다. 이를 활용하여 (r, c)가 어느 변에 위치하는지 알 수 있습니다. 각각의 변에서 시작 숫자를 정해주고 시작 숫자와 차이가 나는 칸수만큼 빼주면 (r, c)의 숫자를 알 수 있습니다.
34를 예로 들면 먼저 시작숫자는 가장 큰 숫자인 49부터 시작하여 밑변 -> 왼쪽 변 -> 윗변 -> 오른쪽 변 순서로 탐색하게 됩니다. 밑변에 없으므로 왼쪽변으로 이동하는데 이때 시작 숫자를 43(=49 - 2 * (4 - 1))으로 변경해줍니다. 왼쪽 변에도 없으므로 시작숫자를 37로 변경해줍니다. 윗변에는 (-3, 0)이 존재하므로 시작 숫자의 위치와 몇칸 차이나는지 계산해주어 리턴해주면 됩니다.
3. 풀이
import sys
sys.stdin = open("input.txt", "r")
r1, c1, r2, c2 = tuple(map(int, input().split()))
board = [
[0] * (c2 - c1 + 1)
for _ in range(r2 - r1 + 1)
]
def getStartNumber(n):
start = 1
for i in range(n + 1):
start += 8 * i
return start
def getNumber(y, x):
n = max(abs(y), abs(x))
#시작 숫자(현재 사각형에서 제일 큰 숫자)
startNumber = getStartNumber(n)
#현재 위치
curY, curX = n, n
# 밑변
if y == n:
return startNumber - (curX - x)
curX *= -1
startNumber -= 2 * n
# 왼변
if x == -n:
return startNumber - (curY - y)
startNumber -= 2 * n
curY *= -1
# 윗변
if y == -n:
return startNumber - (x - curX)
curX *= -1
startNumber -= 2 * n
# 오른변
if x == n:
return startNumber - (y - curY)
max_length = 0
for i in range(r2 - r1 + 1):
for j in range(c2 - c1 + 1):
board[i][j] = getNumber(i + r1, j + c1)
max_length = max(len(str(board[i][j])), max_length)
for i in range(r2 - r1 + 1):
for j in range(c2 - c1 + 1):
for k in range(max_length - len(str(board[i][j]))):
print(' ', end='')
print(board[i][j], end =' ')
print()
'문제 해결 > BOJ' 카테고리의 다른 글
[백준] 스위치 (0) | 2023.05.03 |
---|---|
[백준] 배열 돌리기 4 (0) | 2023.05.02 |
[백준] 등산 마니아 (0) | 2023.04.30 |
[백준] 무기공학 (0) | 2023.04.29 |
[백준] 프렉탈 평면 (0) | 2023.04.27 |