문제 링크
https://www.acmicpc.net/problem/14890
14890번: 경사로
첫째 줄에 N (2 ≤ N ≤ 100)과 L (1 ≤ L ≤ N)이 주어진다. 둘째 줄부터 N개의 줄에 지도가 주어진다. 각 칸의 높이는 10보다 작거나 같은 자연수이다.
www.acmicpc.net
풀이
조건에 따라 구현하면 되는 문제인데, 뭔가 되게 복잡(?)하게 생각해서 예외처리를 계속 하다가 결국 못풀어서 다른 블로그를 참고했다.
각 라인에 대해 지나갈 수 있는 길인지 체크한다.
세로의 경우 파이썬의 zip을 사용하여 간단하게 n*m->m*n 배열로 변경할 수 있고, 이에 대해 체크하면 된다.
시작점을 오른쪽/ 왼쪽으로 구분하여 지나가며 갈 수 있는 길인지 체크한다.
만약 다음 칸과의 차이가 1보다 크면 False를 리턴한다.
1. 오른쪽으로 지나갈 때
다음 칸의 높이가 현재 칸의 높이 + 1일 때, 현재 칸부터 l만큼 전 칸까지 확인하여 경사로를 놓을 수 있는지 체크한다.
범위를 벗어나거나, 이미 경사로가 설치되어 있거나, 높이가 다르면 False를 리턴한다.
경사로를 놓을 수 있는 위치이면 used 배열 (경사로 설치 유무 체크)의 인덱스 값을 True 로 설정한다.
2. 왼쪽으로 지나갈 때
현재 칸의 높이가 다음 칸의 높이 + 1일 때, 다음 칸 부터 l만큼 다음 칸까지 확인하여 경사로를 놓을 수 있는지 체크한다.
범위를 벗어나거나, 이미 경사로가 설치되어 있거나, 높이가 다르면 False를 리턴한다.
경사로를 놓을 수 있는 위치이면 used 배열 (경사로 설치 유무 체크)의 인덱스 값을 True 로 설정한다.
def check(arr):
used = [False] * n
for i in range(n-1):
# 높이 차이가 1 이상
if abs(arr[i] - arr[i+1]) > 1 :
return False
# 오른쪽 탐색
if arr[i] < arr[i+1]:
for j in range(l):
if i-j < 0 or used[i-j] or arr[i] != arr[i-j]:
return False
used[i-j] = True
# 왼쪽 탐색
if arr[i] > arr[i+1]:
for j in range(l):
if i + j + 1 >= n or used[i+j+1] or arr[i+1] != arr[i+j+1]:
return False
used[i+j+1] = True
return True
n, l = map(int,input().split())
graph = []
for _ in range(n):
graph.append(list(map(int,input().split())))
ans = 0
for i in graph:
if check(i):
ans += 1
for i in list(zip(*graph)):
if check(i):
ans += 1
print(ans)
'개발 > algorithm' 카테고리의 다른 글
[백준 16234번] 인구 이동 - python (1) | 2022.10.07 |
---|---|
[백준 15684번] 사다리 조작 - python (0) | 2022.10.07 |
[백준 14889번] 스타트와 링크 - python (0) | 2022.10.07 |
[백준 23288번] 주사위 굴리기2 - python (0) | 2022.10.06 |
[백준 21611번] 마법사 상어와 블리자드 - python (1) | 2022.10.06 |