일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 트랩
- 우선순위
- 프로세스
- 페이지 부재율
- Oracle
- mutex
- 알고리즘
- Algorithm
- 추상화
- 운영체제
- 세마포어
- mips
- 컴퓨터구조
- PYTHON
- 스케줄링
- ALU
- 페이지 대치
- 교착상태
- concurrency
- 동기화
- 단편화
- 페이징
- 가상 메모리
- 백준
- 인터럽트
- fork()
- BOJ
- 기아 상태
- 스레드
- 부동소수점
- Today
- Total
봉황대 in CS
[BOJ15685 - Python] 드래곤 커브 본문
문제
K(K>1)세대 드래곤 커브
= K-1세대 드래곤 커브를 끝 점 기준 90도 시계 방향으로 회전 → 그 끝 점에 붙인 것
풀이
첫번째 풀이
드래곤 커브로 그려진 선분을 역순으로 추적하여 '시계 방향 90도 회전 → 끝 점에 붙이기'를 반복하는 것을 통해 직접 좌표들을 계산했다.
선분의 방향마다 그 다음으로 찍혀야 하는 점의 위치를 고려해주어야 하기 때문에
해당 방향 벡터가 시계 방향으로 90도 회전하면 어느 방향 벡터로 바뀌는지에 대한 딕셔너리를 만들어주었다.
{ 방향 벡터 : 시계 방향 90도 회전 후의 방향 벡터 }
rotate_90 = {(-1, 0): (0, 1), (1, 0): (0, -1), (0, 1): (1, 0), (0, -1): (-1, 0)} # 시계 방향 90도 회전 시 벡터
선분의 거리는 항상 1이기 때문에 "끝 점 - 시계 방향 90도 회전 후의 방향 벡터"를 통해 다음으로 찍히는 점들을 찾아낼 수 있다.
전체 코드는 다음과 같다.
import sys
N = int(sys.stdin.readline().strip())
dragon_input = [] # 시작점 x, 시작점 y, 시작 방향, 세대
for _ in range(N):
dragon_input.append(list(map(int, sys.stdin.readline().split())))
grid = [] # 100 x 100
for _ in range(101):
grid.append(list([False for _ in range(101)]))
direction = [(0, 1), (-1, 0), (0, -1), (1, 0)] # 시작 방향
rotate_90 = {(-1, 0): (0, 1), (1, 0): (0, -1), (0, 1): (1, 0), (0, -1): (-1, 0)} # 시계 방향 90도 회전 시 벡터
for start_x, start_y, d, g in dragon_input:
dragon = [[start_y, start_x], [start_y + direction[d][0], start_x + direction[d][1]]] # 드래곤 커브 좌표 (0세대)
for _ in range(g):
i = len(dragon) - 1
# 드래곤 커브 좌표 구하기
while i >= 1:
y = dragon[i][0] - dragon[i - 1][0]
x = dragon[i][1] - dragon[i - 1][1]
vector = rotate_90.get((y, x))
new_point = [dragon[-1][0] - vector[0], dragon[-1][1] - vector[1]]
dragon.append(new_point)
i -= 1
# 위치 표시
for d_y, d_x in dragon:
grid[d_y][d_x] = True
# 정사각형 개수 구하기
result = 0
for y in range(100):
for x in range(100):
if grid[y][x] and grid[y + 1][x] and grid[y][x + 1] and grid[y + 1][x + 1]:
result += 1
print(result)
어찌저찌 성공하긴 했지만 굉장히 마음에 들지 않는다.
두번째 풀이
사실 알고리즘 관련 블로깅은 처음 하다보니까 어떻게 써야할지 너무 막막해서 다른 분들의 블로그를 열심히 찾아봤는데,
이 과정에서 내 풀이보다 훨씬 나은 아이디어들을 보았다.
바로 다시 코딩 고고.
문제 설명에서 처럼
0 : x좌표가 증가하는 방향 (→)
1 : y좌표가 감소하는 방향 (↑)
2 : x좌표가 감소하는 방향 (←)
3 : y좌표가 증가하는 방향 (↓)
이라고 했을 때
드래곤 커브 세대별로 선분마다의 방향을 쭉 작성해보면
0세대 : 0
1세대 : 0 1
2세대 : 0 1 2 1
3세대 : 0 1 2 1 2 3 2 1
...
조금 더 규칙을 보기 쉽게 작성해보면
0세대 : 0
1세대 : 0 / 1
2세대 : 0 1 / 2 1
3세대 : 0 1 2 1 / 2 3 2 1
...
즉, '이전 세대의 방향 + 1'을 역순으로 이어 붙여주면 되는 것이었다.
이렇게 찾은 규칙으로 수정한 전체 코드는 다음과 같다.
import sys
N = int(sys.stdin.readline().strip())
dragon_input = [] # 시작점 x, 시작점 y, 시작 방향, 세대
for _ in range(N):
dragon_input.append(list(map(int, sys.stdin.readline().split())))
grid = [] # 100 x 100
for _ in range(101):
grid.append(list([False for _ in range(101)]))
# 방향
d_y = [0, -1, 0, 1]
d_x = [1, 0, -1, 0]
for start_x, start_y, d, g in dragon_input:
direction = [d]
for _ in range(g):
for i in range(len(direction) - 1, -1, -1): # range(start, stop, step)
direction.append((direction[i] + 1) % 4)
# 위치 표시
grid[start_y][start_x] = True
for i in direction:
start_y += d_y[i]
start_x += d_x[i]
grid[start_y][start_x] = True
# 정사각형 개수 구하기
result = 0
for y in range(100):
for x in range(100):
if grid[y][x] and grid[y + 1][x] and grid[y][x + 1] and grid[y + 1][x + 1]:
result += 1
print(result)
한 리스트 내에서 좌표들을 쭉 저장하는 것보단
d_y, d_x으로 y값, x값을 따로 저장해주어 호출하는 것이 더 직관적이고 편한 것 같아 해당 방향으로 코드를 고치게 되었다.
만-족
앞으로 주의해야 할 사항
1. 문제를 잘 읽자 !!!!!!
문제에서는 크기가 1×1인 정사각형의 '네 꼭짓점'이 모두 드래곤 커브의 일부인 것의 개수를 물어봤는데, 나는 드래곤 커브의 '네 선분'으로 둘러 쌓여있어야 한다는 것으로 잘못 이해했었다. 다 구현하고 나서야 읭...?하고 깨달아버림
예에에에전부터 많이 실수하는 것인데 문제를 처음부터 잘 읽도록 하자.
2. grid 범위
계속 런타임 에러 (IndexError)가 나서 봤더니, 격자를 선언한 범위 때문에 나는 에러였다.
문제에서는 크기가 100×100인 격자이며 0 ≤ x ≤ 100, 0 ≤ y ≤ 100라고 했기 때문에 아래처럼 선언해주어야 한다.
(101이 아닌 100으로 작성해서 틀린 것이었다.)
grid = [] # 100 x 100
for _ in range(101):
grid.append(list([False for _ in range(101)]))
'Problem Solvings > BOJ' 카테고리의 다른 글
[BOJ20055 - Python] 컨베이어 벨트 위의 로봇 (0) | 2022.07.02 |
---|---|
[BOJ20058 - Python] 마법사 상어와 파이어스톰 (0) | 2022.07.01 |
[BOJ5212 - Python] 지구 온난화 (0) | 2022.06.29 |
[BOJ20057 - Python] 마법사 상어와 토네이도 (0) | 2022.06.28 |
[BOJ14719 - Python] 빗물 (0) | 2022.06.27 |