1일 1PS 77일차!

📚 문제


[골드 1] - 수영장 만들기

💡 풀이 과정


  • 수영장의 최대 높이는 9 이기 때문에 9번의 dfs 탐색을 진행하면 된다. ```

13331 21112 12221

위와 같이 주어진 수영장은 3가지로 나누어 생각할 수 있다.

11111 11111 11111

02220 20002 02220

03330 00000 00000

- 3층의 수영장을 각 층별로 분리한 것이다.
- 벽이 아닌 곳은 0 으로 표현했을 때 위와 같고 각 층별로 벽에 둘러쌓인 곳의 넓이를 더해주면 된다.

<br>

def DFS(h): visited = [[False for _ in range(M)] for _ in range(N)]

# 가장자리 부분에 h 보다 작거나 같은 경우에 stack 에 추가.
stack = []
for i in range(N):
    for j in range(M):
        if i == 0 or j == 0 or i == N - 1 or j == M - 1:
            if pool[i][j] <= h:
                stack.append((i, j))

while stack:
    x, y = stack.pop()
    visited[x][y] = True

    for i in range(4):
        nx = x + dx[i]
        ny = y + dy[i]

        if nx < 0 or ny < 0 or nx >= N or ny >= M or visited[nx][ny]:
            continue

        if pool[nx][ny] >= h:
            visited[nx][ny] = True
        else:
            stack.append((nx, ny))

c = 0
for li in visited:
    c += sum(li)

return (M * N) - c

- 처음에는 가장자리부분을 모두 확인해서 전체 둘러쌓인 넓이를 구하려 했다.

333333 311113 313313 311113 333333


- 하지만 위처럼 내부의 벽에 대해서 계산할 수도 없다.

<br>

- 따라서 모든 칸을 방문하는 것을 보장해야한다.
- 각 층의 넓이를 더해주기 위해서는 모든 칸에 대해서 bfs 혹은 dfs 를 진행한다.
- (0, 0) 부터 시작해서 visited 로 구역을 관리하며 모든 곳에 갈 수 있도록 한다.
- 벽의 경우는 continue 하고 벽보다 작은 경우에 대해서만 찾아낸다.
- 탐색 중에 밖으로 벗어나는 경우는 지금까지 계산한 물이 모두 밖으로 흘러가버린다는 뜻이므로 flag = False 이다.
- flag = True 인 경우에만 물이 갇힐 수 있고 이때 cnt 값을 반환하면 된다.

# 📌포인트

---

- visited
    - visited 의 선언 위치에 따라 정답이 바뀔 수 있다.
    - 초기값은 미리 visited 를 설정하고
    - 다음 bfs, dfs 를 진행하기 전에 visited 를 확인하도록 하자!


# 💻 코드

---




dx = [0, 1, 0, -1] dy = [1, 0, -1, 0]

N, M = map(int, input().split()) pool = [list(map(int, input())) for _ in range(N)] cnt = 0

#dfs def dfs_height(h): visited = [[False for _ in range(M)] for _ in range(N)] water = 0 for i in range(N): for j in range(M): # 만약 h 와 비교했을 때 물이 채워지지 못하는 벽이라면 visited 만 다시 점검하고 넘어간다. if pool[i][j] >= h: visited[i][j] = True continue

        # 아직 방문하지 않았다면 바로 dfs 실행
        if not visited[i][j]:
            stack = []
            visited[i][j] = True
            stack.append((i, j))
            cnt = 1
            flag = True

            while stack:
                x, y = stack.pop()
                visited[x][y] = True

                for k in range(4):
                    nx = x + dx[k]
                    ny = y + dy[k]

                    if nx < 0 or ny < 0 or nx >= N or ny >= M:
                        flag = False
                        continue
                    if visited[nx][ny]:
                        continue

                    if pool[nx][ny] < h:
                        visited[nx][ny] = True
                        cnt += 1
                        stack.append((nx, ny))

            # 다 끝나고 flag = Flag 라면 물이 다 빠져나간다.
            if flag:
                water += cnt

return water

result = 0 for i in range(10): result += dfs_height(i)

print(result)

```

업데이트:

댓글남기기