경사로

최민수·2023년 4월 5일
0

알고리즘

목록 보기
47/94
⭐️
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 배열을 둠으로써 해결을 한다.


풀지 못한 이유 분석

개인적으로 가장 놓쳤다고 생각하는 아이디어는 바로 전과 비교를 하는 전략이라고 생각한다.

나는 처음에 쭉 순회를 하면서 경사로 길이만큼 앞의 것들의 조건을 체크해야 한다고 생각했었다. 그런데 그런 식으로 하면 경사로를 놓는 조건이 됐을 때 스킵해야 되는 길들이 중간에 생겨버리고, 예외 처리 조건들을 많이 달아야 됐었다.

결국에 그런 식으로 모든 케이스를 통과할 순 없겠다 싶었다. 하지만 바로 전과 비교를 해서 이전 상황들에 대해 내리막 또는 오르막 설치 여부를 결정하게 되면 스킵하는 상황이 생기지 않을 뿐더러 다시 뒤를 확인하지 않아도 되기에 따로 예외 처리를 해야 할 조건들이 많이 사라지게 되는 것이다.

깔끔하고 간결한 풀이다. 내가 배울 점이 많은 코드라고 생각했다.


문제 출처: https://www.acmicpc.net/problem/14890

profile
CS, 개발 공부기록 🌱

0개의 댓글