코딩문제 풀이

4963번 섬의 개수

student513 2020. 2. 10. 15:46

 

 

4963번: 섬의 개수

문제 정사각형으로 이루어져 있는 섬과 바다 지도가 주어진다. 섬의 개수를 세는 프로그램을 작성하시오. 한 정사각형과 가로, 세로 또는 대각선으로 연결되어 있는 사각형은 걸어갈 수 있는 사각형이다.  두 정사각형이 같은 섬에 있으려면, 한 정사각형에서 다른 정사각형으로 걸어서 갈 수 있는 경로가 있어야 한다. 지도는 바다로 둘러쌓여 있으며, 지도 밖으로 나갈 수 없다. 입력 입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 테스트 케이스의 첫째 줄에는

www.acmicpc.net

오랜만에 BFS 문제를 풀어봤다. 

 

요즘은 소마 코테를 준비하느라 브루트포스, DP, BFS 위주로 푸는 중이다.

 

각설하고, 입력된 그래프의 연결요소의 개수를 구하는 문제.

 

연결 요소란, '무향 그래프에서 서로 다른 두 정점이 경로로 연결되어 있으면서 상위 그래프의 추가 정점이 없는 부분 그래프'라고 한다.

그림으로 보면 G라는 그래프에 연결요소는 H0, H1 총 2개가 있는 것이다.

 

이 문제를 푸는데에 고려한 부분은

 

"연결상태를 어떻게 저장할까?" 라는 것이었다.

 

2차원 배열에 저장하자니 x, y 좌표 두 개를 동시에 저장할 수가 없다. 

 

해법은 queue<pair<int x,int y>>로 저장하는 것. 

 

큐가 텅 빌때까지 루프를 시켜주도록 한다.

 

#include <iostream>
#include <cstring>
#include <queue>
using namespace std;

queue<pair<int,int>> que;
int map[51][51];
bool visited[51][51];
int dir[8][2] = { {-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1} };
int w, h;
int result;

void bfs(int x, int y) {
	int curr_x, curr_y;
	visited[x][y] = true;
	que.push(make_pair(x, y));
	while (!que.empty()) {
		for (int i = 0; i < que.size(); i++) {
			int curr_x = que.front().first; int curr_y = que.front().second;
			que.pop();
			for (int k = 0; k < 8; k++) {
				int dir_x = curr_x + dir[k][0]; int dir_y = curr_y + dir[k][1];
				if (0 <= dir_x && dir_x < h && 0 <= dir_y && dir_y < w) {
					if (!visited[dir_x][dir_y] && map[dir_x][dir_y] == 1) {
						visited[dir_x][dir_y] = true;
						que.push(make_pair(dir_x, dir_y));
					}
				}
			}
		}
	}
	result++;
}

int main() {
	while (true) {
		memset(map, 0, sizeof(map));
		memset(visited, false, sizeof(visited));
		result = 0;
		cin >> w >> h;
		if (!w && !h)break;
		for (int i = 0; i < h; i++) {
			for (int j = 0; j < w; j++) {
				cin >> map[i][j];
			}
		}

		for (int i = 0; i < h; i++) {
			for (int j = 0; j < w; j++) {
				if (map[i][j] && !visited[i][j]) {
					bfs(i, j);
					
				}
			}
		}
		cout << result << "\n";
	}
	return 0;
}

'코딩문제 풀이' 카테고리의 다른 글

14500번 테트로미노  (0) 2020.02.13
2225번 합분해  (0) 2020.02.11
11727번 2xn 타일링 2  (0) 2020.02.07
13908번 비밀번호  (0) 2020.02.04
17144번 미세먼지 안녕!  (0) 2020.01.30