[PYTHON] 백준 2667 - 단지번호붙이기

이또삐(이민혁)·2023년 4월 29일

CODINGTEST

목록 보기
78/96
post-thumbnail

https://www.acmicpc.net/problem/2667

성능 요약

메모리: 114488 KB, 시간: 120 ms

분류

너비 우선 탐색, 깊이 우선 탐색, 그래프 이론, 그래프 탐색

문제 설명

<그림 1>과 같이 정사각형 모양의 지도가 있다. 1은 집이 있는 곳을, 0은 집이 없는 곳을 나타낸다. 철수는 이 지도를 가지고 연결된 집의 모임인 단지를 정의하고, 단지에 번호를 붙이려 한다. 여기서 연결되었다는 것은 어떤 집이 좌우, 혹은 아래위로 다른 집이 있는 경우를 말한다. 대각선상에 집이 있는 경우는 연결된 것이 아니다. <그림 2>는 <그림 1>을 단지별로 번호를 붙인 것이다. 지도를 입력하여 단지수를 출력하고, 각 단지에 속하는 집의 수를 오름차순으로 정렬하여 출력하는 프로그램을 작성하시오.

https://camo.githubusercontent.com/a8eb21e7db7330851f988504fcbb4822fced9979830a4285f4d5ae3f147890c6/68747470733a2f2f7777772e61636d696370632e6e65742f75706c6f61642f696d616765732f49545648397731476636654352645468666b65674255534f4b642e706e67

입력

첫 번째 줄에는 지도의 크기 N(정사각형이므로 가로와 세로의 크기는 같으며 5≤N≤25)이 입력되고, 그 다음 N줄에는 각각 N개의 자료(0혹은 1)가 입력된다.

출력

첫 번째 줄에는 총 단지수를 출력하시오. 그리고 각 단지내 집의 수를 오름차순으로 정렬하여 한 줄에 하나씩 출력하시오.


아이디어, 문제풀이

  • 두가지를 카운트 해야한다.
    1. 총 단지수
    2. 각 단지내 집의 수를 오름차순
  • 이전에 풀이했던 빙산문제의 대륙 세는법
  • dfs, bfs 모두 상관없기에, 나한테 더익숙한 dfs 사용!

TROUBLE SHOOTING

  • 이전에 풀었던 문제들을 붙여놓은 느낌. 더 간단히 생각하면, 사실 빙산 문제보다도 쉬운 문제다. 직접 print를 해보거나, 코드의 흐름을 읽어서, 내가 원하는 두가지의 값을 받아내면 된다. 나는 항상 배열에 저장하는 습관이 있는데, append를 활용하면 인덱스 에러 없이 일단 출력해서 확인할 수 있기 때문이다.

  • 나는 이 while문을 for문 안에 집어넣는 방식이 생각해내기 참 어려웠던것 같다. 빙산문제를 풀어봤기 때문에 다행히 접근해낼 수 있었다.

        for i in range(n):
            for j in range(n):
                if graph[i][j] == 1 and visit[i][j] == 0:
                    value += 1  # 대륙을 발견할 때마다 value를 증가시킵니다.
                    house_count = 0
                    stack.append((i, j))
                    visit[i][j] = 1
    
                    while stack:
                        x, y = stack.pop()
    
                        for k in range(4):
    
                            nx = x + dx[k]
                            ny = y + dy[k]
    
                            if 0 <= nx < n and 0 <= ny < n and visit[nx][ny] == 0:
                                if graph[nx][ny] == 1:
                                    visit[nx][ny] = 1
                                    house_count += 1
                                    stack.append((nx,ny))
  • 이 문제에서 거의 30분 정도를 낭비한 부분이 있다.
    house.sort()
    print(dfs(graph, visit))
    for i in range(len(house)):
        print(house[i])
    이 문제의 예제 출력값은 3 / 7,8,9 였는데, 이 출력값은 sort가 되지 않아도 오름차순으로 출력된다. 나는 내가 출력된 결과를 잘 sort하고 있는줄 알았다… 하지만… 비어있는 배열을sort하고 있었을뿐…. 내 코드에서 반례들을 제대로 판별해 내고 있지 못한다고 생각해서 애꿎은 dfs 함수만 고치고 있었다. 풀이를 빨리 진행해야되는 상황이라도, 항상 꼼꼼하게 체크하고 넘어가야한다. 아쉬웠다 ;ㅁ;

코드

#https://www.acmicpc.net/problem/2667
#단지번호붙이기
#2667

n = int(input())

graph = []
for _ in range(n):
    a = list(map(int, input().strip()))
    graph.append(a)

# print(graph)

visit = [[0] * n for _ in range(n)]

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

house = []

def dfs(graph, visit):

    stack = []
    # visit[a][b] == 1
    # stack.append((a,b))
    value = 0

    for i in range(n):
        for j in range(n):
            if graph[i][j] == 1 and visit[i][j] == 0:
                value += 1  # 대륙을 발견할 때마다 value를 증가시킵니다.
                house_count = 0
                stack.append((i, j))
                visit[i][j] = 1

                while stack:
                    x, y = stack.pop()

                    for k in range(4):

                        nx = x + dx[k]
                        ny = y + dy[k]

                        if 0 <= nx < n and 0 <= ny < n and visit[nx][ny] == 0:
                            if graph[nx][ny] == 1:
                                visit[nx][ny] = 1
                                house_count += 1
                                stack.append((nx,ny))

                house.append(house_count)
                # print(house)

    return value

print(dfs(graph, visit))
house.sort()
for i in range(len(house)):
    print(house[i])
    

# print(visit)
profile
해보자! 게임 클라 개발자!

0개의 댓글