#1388

zzwwoonn·2022년 5월 9일
0

Algorithm

목록 보기
16/71

문제를 처음 보자마자 4963번 섬의 개수 문제가 생각이 났고 dfs로 풀어야겠다고 생각했다. 이중 for 문으로 각 지점을 돌면서 dfs 를 돌리고 방문했던 지점은 다시 방문하지 않는다. 나름 쉽게? 풀릴거라 생각했고 결론적으로는 정답도 맞췄다. 하지만 도중에 있었던 오류 해결(예외 처리) 과정을 기록해두고 정답을 띄운 후 구글에서 찾은 모범 답안이 너무나 신박해서 꼭 기록을 해두고 싶다.

풀이 1

row, col = map(int, input().split())
inputMap = [[ "-" for i in range(0,col+1)] for j in range(0, row+1)]
visitMap = [[ 0 for i in range(0,col+1)] for j in range(0, row+1)]
# print(inputMap)
cnt = 0

for i in range(0, row):
    onerow = input()
    for j in range(0, len(onerow)):
        if onerow[j] == "|":
            inputMap[i][j] = "|"
# print(inputMap)
# 입력 어떻게 깔끔하게 받는지 코드 보기

def dfs(startRow, startCol):
    global cnt

    # input()
    # print(startRow, startCol, " dfs 시작하려고 들어옴")

    if startRow >= row  or startRow < 0 or startCol < 0 or startCol >= col:
        # print("범위 넘어서 리턴")
        return

    if visitMap[startRow][startCol] == 1:
        # print("이미 왔던 곳이라 리턴")
        return
    
    visitMap[startRow][startCol] = 1
    # print(startRow, startCol, " 방문 체크")
    # if startRow == row-1 or startCol == col-1:
    #     return

    if inputMap[startRow][startCol] == '-':
        # print(startRow, startCol, " is -")
        if startCol < col:
            if inputMap[startRow][startCol+1] == '-':
                dfs(startRow,startCol+1)
        else:
            return
    else:
        # print("here is |")
        if startRow < row:
            if inputMap[startRow+1][startCol] != '-':
                dfs(startRow+1,startCol)
        else:
            return

for i in range(0, row):
    for j in range(0, col):
            if visitMap[i][j] != 1:
                # print("i = ", i, "j = ", j)
                cnt += 1
                dfs(i,j)
                # print("cnt = ", cnt )
print(cnt)

처음에 로직은 너무나 완벽하다고 생각했지만 계속 index error가 나왔다.

바로 젤 마지막 row, col을 확인할 때 바로 다음에 나오는 row 와 col이 정해진 맵(inputMap, visitMap)의 최대 인덱스를 초과하는 것이다. 정의되어 있지 않은 인덱스이므로 값을 읽어올 수가 없었다. 어떻게 예외처리를 해줘야할 까 계속 했지만 해결 방법은 의외로 간단했다. 그냥 정의해놓은 Map의 사이즈를 1씩 키워주면 된다.

그럼 너무.. 야매로 해결하는 것이 아닌가? 라는 의문이 들었다. 하지만 전혀 그렇지 않다. 나는 오히려 정석에 가깝다고 생각한다. 왜냐하면 dfs를 처음 들어왔을 때 if 조건문으로 startRow 와 startCol 이 최대 인덱스를 넘기는지 판단해서 넘어가면 밑으로 내려가지 않고 바로 return 하기 때문이다.

이렇게 정답을 띄우고 혹시 더 간단한 풀이가 있을지 구글에다가 문제를 쳐봤는데 몇줄 안되는 정말 간단한 코드가 있었다.

풀이 2

row, col = map(int, input().split())
cnt = 0
# inputMap = [[ "-" for i in range(0,col+1)] for j in range(0, row+1)]
# for i in range(0, row):
#     onerow = input()
#     for j in range(0, len(onerow)):
#         if onerow[j] == "|":
#             inputMap[i][j] = "|"

# 입력 깔끔하게 받기

inputMap = []
for _ in range(row):
    inputMap.append(list(input()))

for i in range(row):
        a = ''
        for j in range(col):
            if inputMap[i][j] == '-':
                if inputMap[i][j] != a:
                    cnt += 1
            a = inputMap[i][j]

for j in range(col):
    a = ''
    for i in range(row):
        if inputMap[i][j] == '|':
            if inputMap[i][j] != a:
                cnt += 1
        a = inputMap[i][j]

print(cnt)

for 문을 2번 돌려 row별로 한번, col별로 한번(가로 세로 따로 따로) cnt를 세어주는 방법이다. row를 기준으로 cnt를 세어줄 땐 "-"로 시작하여 다른 문자로 바뀔 때마다 cnt를 증가시켜 주면 된다. (col은 반대로)

이게 정석..? 인가 싶지만 처음 이 문제를 봤을 때 이 풀이를 생각해내기란 정말 쉽지 않을 것이다. (사실 말이 안된다 생각한다. 문제를 엄청 많이 풀어봐서 이런 유형을 많이 다뤄봤으면? 몰라도)

구글에서 가져온 정답 코드는 입력 값을 받는 것도 정말 깔끔하고 심플하게 받아왔다. 이런 부분은 내 걸로 만들어 앞으로 써먹어야겠다.

inputMap 설정하기

내가 짰던 코드

 inputMap = [[ "-" for i in range(0,col+1)] for j in range(0, row+1)]
 for i in range(0, row):
     onerow = input()
     for j in range(0, len(onerow)):
         if onerow[j] == "|":
             inputMap[i][j] = "|"

정답 코드

inputMap = []
for _ in range(row):
    inputMap.append(list(input()))

list 를 함수를 모르는게 아닌데 왜 이 생각을 못했을까
앞으로 꾸준하게 문제를 많이 풀어봐야 한다. 잔디 열심히 채우자!!!!

0개의 댓글