📌 문제
1. 격자의 각 셀에는 지형의 높이가 정수로 주어져 있다.

2. 목표는 가로 또는 세로 방향으로 활주로를 건설할 수 있는 경우의 수를 구하는 것이다.

3. 같은 줄에 높이가 다른 구간이 있다면 반드시 아래와 같은 경사로를 설치해줘야 한다.

- 경사로의 길이: X ( 2 <= X <= 4)
- 경사로의 높이: 1
4. 아래는 문제에서 주어진 모든 경우를 나타낸 것이다.

4. 문제에서 주어진 경사로 건설 규칙에 따라 경사로를 건설하면, 예제에 대한 정답은 다음과 같이 7이 된다.

📌 풀이
Code
T = int(input())
for tc in range(1, 1+T):
N, X = map(int, input().split()) # N: 맵 크기, X: 활주로 길이
arr = [list(map(int, input().split())) for _ in range(N)] # 맵
CNT = 0 # 활주로를 건설할 수 있는 경우의 수 (정답 변수)
# 세로로 읽기
for c in range(N):
prev = arr[0][c] # 이전 위치의 높이
conti = 1 # 동일 높이 연속으로 나온 횟수
visited = [0] * N # 방문 리스트 (이미 건설된 곳에 또 건설하는 것 막기 위함)
for r in range(1, N):
# 이미 건설된 곳이면 넘어가
if visited[r]:
continue
cur = arr[r][c] # 현재 위치의 높이
conti += 1
# 순서대로 읽다가 높이가 한번에 2 이상 차이나면 그 줄은 제외
if abs(cur - prev) >= 2:
break
# 한 칸 내려갔으면 지금부터 동일 높이 연속 X개 여부 확인
if cur - prev == -1:
break_flag = False
for k in range(X):
nr = r + k
# 배열을 벗어나지 않으면서 동일 높이가 연속으로 나오면
if nr < N and cur == arr[nr][c]:
visited[nr] = 1 # 방문 처리
# 배열 벗어나거나 높이가 바뀌면 break
else:
break_flag = True
if break_flag:
break
conti = 0 # 동일 높이 연속 횟수 초기화
# 한 칸 올라갔으면 지금까지 동일 높이 연속 X개 여부 확인
elif cur - prev == 1:
conti -= 1
if conti < X:
break
conti = 1 # 동일 높이 연속 횟수 초기화
prev = cur
# for-else문: 한 번도 break에 걸리지 않았다면
else:
CNT += 1
# 가로로 읽기
for r in range(N):
prev = arr[r][0] # 이전 위치의 높이
conti = 1 # 동일 높이 연속으로 나온 횟수
visited = [0] * N # 방문 리스트 (이미 건설된 곳에 또 건설하는 것 막기 위함)
for c in range(1, N):
# 이미 건설된 곳이면 넘어가
if visited[c]:
continue
cur = arr[r][c] # 현재 위치의 높이
conti += 1
# 순서대로 읽다가 높이가 한번에 2 이상 차이나면 그 줄은 제외
if abs(cur - prev) >= 2:
break
# 한 칸 내려갔으면 지금부터 동일 높이 연속 X개 여부 확인
if cur - prev == -1:
break_flag = False
for k in range(X):
nc = c + k
# 배열을 벗어나지 않으면서 동일 높이가 연속으로 나오면
if nc < N and cur == arr[r][nc]:
visited[nc] = 1 # 방문 처리
# 배열 벗어나거나 높이가 바뀌면 break
else:
break_flag = True
if break_flag:
break
conti = 0 # 동일 높이 연속 횟수 초기화
# 한 칸 올라갔으면 지금까지 동일 높이 연속 X개 여부 확인
elif cur - prev == 1:
conti -= 1
if conti < X:
break
conti = 1 # 동일 높이 연속 횟수 초기화
prev = cur
# for-else문: 한 번도 break에 걸리지 않았다면
else:
CNT += 1
print(f'#{tc} {CNT}')
Solution
1. 각 열과 각 행을 따로 읽으며 활주로 가능 여부를 확인

2. 앞으로 가다가 높이가 2 이상 차이나면 종료
3. 현재 높이와 1 차이가 나는 지형으로 이동했을 시 경사로 설치 여부 확인
- 낮은 지형으로 내려갔을 때
- conti를 0으로 바꾸고 X개의 칸 만큼 방문 처리 (X개만큼 못가면 그 줄은 탈락)
- 방문처리 된 칸은 이동하더라도 conti가 늘어나지 않음
- 높은 지형으로 올라갔을 때
- 지금까지의 conti(동일한 높이인 칸이 연속으로 나온 횟수)가 X보다 작으면 그 줄은 탈락
- 비교 후에 conti는 1로 변경 (새로운 칸에 올라온 상태이므로)

4. 각 줄을 확인하면서 break 조건에 단 한번도 걸리지 않은 경우에만 CNT 1 증가시키기
- for-else 문 활용
5. 모든 줄을 다 확인한 후, CNT 출력
깨달은 점
그냥 빡구현 문제라.. 삽질하며 깨달은 건 반례를 잘 찾아야 한다는 것..
그리고 가장 중요한 것은..
키보드에 손을 올리기 전에 완벽하게 설계하고 시작하는 습관을 들이자.
'Coding Test > SWEA' 카테고리의 다른 글
[SWEA] SWEA 1242 암호코드 스캔 (Python) - Simulation (0) | 2024.09.03 |
---|---|
[SWEA] 5215 햄버거 다이어트 (Python) - Backtracking (1) | 2024.08.29 |
[SWEA] 1227 미로2 (Python) - DFS/BFS (0) | 2024.08.25 |
[SWEA] 11315 오목 판정 (Python) - Simulation (0) | 2024.08.18 |