⭐️
N, L = map(int, input().split())
maps = [list(map(int, input().split())) for _ in range(N)]
answer = 0
def checkPath(line):
for i in range(1, N):
if abs(line[i] - line[i-1]) > 1:
return False
# 내리막길 설치 상황
if line[i] < line[i-1]:
for j in range(L):
if i+j >= N or line[i] != line[i+j] or slopeExists[i+j]:
return False
if line[i] == line[i+j]:
slopeExists[i+j] = True
# 오르막길 설치 상황
elif line[i] > line[i-1]:
for j in range(L):
if i-1-j < 0 or line[i-1] != line[i-1-j] or slopeExists[i-1-j]:
return False
if line[i-1] == line[i-1-j]:
slopeExists[i-j-1] = True
return True
# Row 체크
for r in range(N):
slopeExists = [False] * N
if checkPath([maps[r][j] for j in range(N)]):
answer += 1
# Column 체크
for r in range(N):
slopeExists = [False] * N
if checkPath([maps[j][r] for j in range(N)]):
answer += 1
print(answer)
구현을 시작하면서 생각보다 로직이 꼬이고 조건을 여러 개 달면서 디버깅을 하다보니 아, 이렇게 하는거 아니다. 이런 식으로 짜면 나중에 엣지 케이스에서 분명히 걸려서 통과 못한다
는 생각이 강하게 들었다.
결국 엣지 케이스에서 걸려서 구글링으로 답을 봤는데, 생각보다 로직이 간단해서 놀랐다.
엣지 케이스 조건 처리를 위해
일일히 if문
으로 처리하면100프로 틀렸다
고 생각하자^^
그 때는과감히 접고
큰 케이스 분류를 한 뒤 공통되는 로직으로 처리될 수 있나 빠르게 방향을 틀어야 한다.
이 문제의 경우 행 방향, 열 방향
으로 첫번째 케이스 분류를 하고 포인트가 되는 부분은 내리막길과 오르막길
케이스로 나누는 분류다.
우선 내리막길과 오르막길을 만드는 상황이 달라야 함
을 이해하고, 또 이 둘의 공통 처리 로직은 똑같음
을 이해해야 한다.
즉, 비교 대상이 현재 위치와 경사로를 둘 부분들인지, 전 위치와 경사로를 둘 부분들인지의 차이다.
경사로 겹침의 문제는 Slope boolean 배열
을 둠으로써 해결을 한다.
개인적으로 가장 놓쳤다고 생각하는 아이디어는
바로 전과 비교
를 하는 전략이라고 생각한다.
나는 처음에 쭉 순회를 하면서 경사로 길이만큼 앞의 것들의 조건을 체크
해야 한다고 생각했었다. 그런데 그런 식으로 하면 경사로를 놓는 조건이 됐을 때 스킵
해야 되는 길들이 중간에 생겨버리고, 예외 처리 조건들
을 많이 달아야 됐었다.
결국에 그런 식으로 모든 케이스를 통과할 순 없겠다 싶었다. 하지만 바로 전과 비교를 해서 이전 상황들에 대해 내리막 또는 오르막 설치 여부를 결정
하게 되면 스킵하는 상황이 생기지 않을 뿐더러 다시 뒤를 확인하지 않아도 되기에 따로 예외 처리를 해야 할 조건들이 많이 사라지게 되는 것이다.
깔끔하고 간결한 풀이다. 내가 배울 점이 많은 코드라고 생각했다.