https://www.acmicpc.net/problem/1022
어렵다.. 출력할 부분만 어떻게 만들어줘야하는지 감이 잘 안와서 어려웠던 문제이다. 또한 모눈종이에서 생각하는 좌표와 실제로 출력해줄 부분에서의 좌표 변환이 어려웠다 (board[x - r1][y - c1]) ㅠㅠ
문제 푸는 아이디어
1. 구현 자체는 소용돌이를 모두 구현한다고 생각하되, 배열은 출력할 크기인 (c2-c1+1) * (r2-r1+1)으로만 초기화해준다.
board = [[0] * (c2-c1+1) for _ in range(r2-r1+1)]
그리고 x, y 가 board 범위에 속하는 경우에만 num 을 board에 기록한다.
x, y = 0, 0으로 초기화하여 생각했으므로, 실제 board에서의 위치는 board[x - r1][y - c1] 인 것에 주의해야 한다 !!!!
2. dx, dy 방향표는 우 -> 상 -> 좌 -> 하 로 만들어 주었다 여기서 index 0 은 우방향
3. 소용돌이 규칙은 우,상 / 좌좌, 하하 / 우우우, 상상상 ... 직접 적으면서 알아냈다 (낯이 익다)
- 한 방향을 length 만큼 반복한다
- 같은 length를 사용하는건 2번반복하고, length 길이를 하나씩 늘려준다.
4. 소용돌이 방향 전환은 dx, dy 를 이용해서 dir 를 배열의 인덱스라고 생각하고 1씩 증가시킨 후 4로 나눈 나머지를 이용하였다.
5. num 은 1씩 증가시켜준다.
6. num 을 실제 board에 표기했다면 count_max_num 을 num으로 갱신한다. count_max_num 값은 나중에 예쁘게 출력할 때 길이가 필요해서 저장해 둘 필요가 있다
# python 통과 못함 pypy만
import sys
input = sys.stdin.readline
r1, c1, r2, c2 = map(int, input().split())
# 시계 반대 방향 우 상 좌 하
# 우 or 좌 방향에서 칸수 1 증가함
dx = [0, -1, 0, 1]
dy = [1, 0, -1, 0]
board = [[0] * (c2-c1+1) for _ in range(r2-r1+1)]
x, y = 0, 0 # 시작점
size = (c2-c1+1) * (r2-r1+1)
# 칸 채우기
length = 1
dir = 0
num = 1 # 칸에 채울 숫자
count_max_num = 0 # 실제로 넣은 숫자중에 가장 큰 숫자
while size > 0:
# 같은 length 2번 반복 후, length + 1
for i in range(2):
for j in range(length):
if r1 <= x <= r2 and c1 <= y <= c2: # 칸에 넣을 수 있으면 기록 아니면 버리기
board[x - r1][y - c1] = num
count_max_num = num
size -= 1
x += dx[dir]
y += dy[dir]
num += 1
dir = (dir+1) % 4 # 방향 전환
length += 1
blank = len(str(count_max_num))
for i in range(r2 - r1 + 1):
for j in range(c2 - c1 + 1):
print(str(board[i][j]).rjust(blank), end=" ")
print()
'Programming Languages > Python' 카테고리의 다른 글
[Python] any() 함수 (0) | 2023.06.26 |
---|---|
[Python] Conda 설치 및 가상환경 생성 (0) | 2023.05.20 |
[Python] 2차원 배열 90도 회전하기 (시계방향) (0) | 2023.01.13 |
[백준] 17281번: 야구 (Python/파이썬) (0) | 2022.12.24 |
[Python] ATM 프로그램/은행 프로그램 파이썬으로 만들기 (파일 입출력으로 데이터 저장) (0) | 2022.11.10 |