-
[백준 / Python] 2667번 단지번호붙이기 | 초코더알고리즘/백준 2020. 1. 18. 18:03
https://www.acmicpc.net/problem/2667
2667번: 단지번호붙이기
<그림 1>과 같이 정사각형 모양의 지도가 있다. 1은 집이 있는 곳을, 0은 집이 없는 곳을 나타낸다. 철수는 이 지도를 가지고 연결된 집들의 모임인 단지를 정의하고, 단지에 번호를 붙이려 한다. 여기서 연결되었다는 것은 어떤 집이 좌우, 혹은 아래위로 다른 집이 있는 경우를 말한다. 대각선상에 집이 있는 경우는 연결된 것이 아니다. <그림 2>는 <그림 1>을 단지별로 번호를 붙인 것이다. 지도를 입력하여 단지수를 출력하고, 각 단지에 속하는 집의 수
www.acmicpc.net
접근법
좌표문제를 풀때는 dx,dx라는 리스트를 선언해주어서 풀면 좀더 접근이 쉬울것같습니다.
dx=[-1,0,1,0] dy=[0,1,0,-1] dx,dx가 나타내는 것은 for문에서
i가 0일때는 좌표 (x,y)의 좌, i가 0일때는 좌표 (x,y)의 상,i가 0일때는 좌표 (x,y)의 우,i가 0일때는 좌표 (x,y)의 하
우선 이중 for문을 통해 a[x][y]를 0,0부터 n,n까지 비교해줍니다.
1. a[i][j] == '1'일 경우만 cnt를 0으로 대입한후(다른 아파트 단지들을 세고 나면 cnt가 증가해있으므로)
dfs(i,j) 실행
2. dfs(x,y) 함수
2-1. cnt변수 global로 선언. 현재 방문한 좌표 '0'으로 대입(반복해서 방문하는 일이 없게 해줌)
2-2. cnt변수 증가(해당 단지의 개수 1씩 증가)
2-2. for문 상,하,좌,우 4번 반복
2-3. a[nx][ny] 현재 비교중인 a[x][y] 의 상(or 하 or 좌 or 우) 좌표가 1인 경우에 다시 dfs재귀호출
만약 1이 아니라면? for문 탈출해서 다른 상(or 하 or 좌 or 우) 비교.
2-4. dfs재귀호출할때마다(즉, 집이 있는 곳일때마다='1'일때마다) cnt 증가
2-5. 더이상 '1'인 곳이 없으면(=집이 없으면) 함수 종료.
3. dfs 함수를 실행한 후 나온 cnt는 apt리스트에 추가.
4. 모든 좌표에 이런 과정을 반복.
5. cnt변수를 저장해둔 apt리스트의 길이 출력.
6. apt리스트 정렬.
7. apt리스트에 들은 단지수 출력.
나의풀이
import sys dx=[-1,0,1,0] dy=[0,1,0,-1] n=int(sys.stdin.readline()) a=[list(sys.stdin.readline()) for _ in range(n)] cnt=0 apt=[] def dfs(x,y): global cnt a[x][y] = '0' #방문한 곳은 0으로 cnt+=1 for i in range(4): nx = x + dx[i] #i=0일때 (nx,ny)는 좌 , i=1일때 (nx,ny)는 상 ny = y + dy[i] if nx < 0 or nx >= n or ny < 0 or ny >=n: continue if a[nx][ny] == '1': dfs(nx,ny) for i in range(n): for j in range(n): if a[i][j] == '1': cnt= 0 dfs(i,j) apt.append(cnt) print(len(apt)) apt.sort() for i in apt: print(i)
'알고리즘 > 백준' 카테고리의 다른 글
[백준 / Python] 2178번 미로 탐색 | 초코더 (0) 2020.01.19 [백준 / Python] 1012번 유기농 배추 | 초코더 (2) 2020.01.18 [백준 / Python] 2606번 바이러스 | 초코더 (0) 2020.01.17 [백준 / Python] 1260번 DFS와 BFS | 초코더 (0) 2020.01.17 [백준 / Python] 1205번 등수 구하기 | 초코더 (0) 2020.01.16