문제
4963번: 섬의 개수
입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 테스트 케이스의 첫째 줄에는 지도의 너비 w와 높이 h가 주어진다. w와 h는 50보다 작거나 같은 양의 정수이다. 둘째 줄부터 h개 줄에는 지도
www.acmicpc.net
풀이
그래프 탐색, 너비 우선 탐색
간단한 너비 우선 탐색 문제로, 8방향만 주의하면 된다.
지도의 (0, 0)부터 탐색을 시도하며, 현재 타일이 방문하지 않은 섬이라면 해당 타일부터 너비 우선 탐색을 실시한다. 상하좌우 대각 8방향에서 방문하지 않은 섬이 있다면 방문하고 이를 반복한다. 탐색이 종료되면 시작한 타일이 포함된 섬을 하나 방문한 것으로 섬의 개수가 1 증가한다.
코드
#include <iostream>
#include <queue>
using namespace std;
int w, h;
int m[50][50];
bool visited[50][50];
int move_x[8] = { 0, 0, 1, -1, -1, -1, 1, 1 };
int move_y[8] = { 1, -1, 0, 0, -1, 1, -1, 1 };
int numIslands()
{
memset(visited, false, sizeof(visited));
int result = 0;
// w, h 주의
for (int i = 0; i < h; ++i)
{
for (int j = 0; j < w; ++j)
{
if (m[i][j] == 1 && visited[i][j] == false)
{
queue<pair<int, int>> q;
q.push(make_pair(i, j));
visited[i][j] = true;
while (!q.empty())
{
int current_x = q.front().first;
int current_y = q.front().second;
q.pop();
// 상하좌우, 대각 8방향, 너비 우선 탐색
for (int k = 0; k < 8; ++k)
{
int next_x = current_x + move_x[k];
int next_y = current_y + move_y[k];
if (next_x < 0 || next_x >= h || next_y < 0 || next_y >= w
|| visited[next_x][next_y] == true || m[next_x][next_y] == 0)
{
continue;
}
q.push(make_pair(next_x, next_y));
visited[next_x][next_y] = true;
}
}
result++;
}
}
}
return result;
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(NULL);
cout.tie(NULL);
// w, h 주의
while (cin >> w >> h)
{
if (w == 0 && h == 0)
{
break;
}
for (int i = 0; i < h; ++i)
{
for (int j = 0; j < w; ++j)
{
cin >> m[i][j];
}
}
cout << numIslands() << '\n';
}
return 0;
}
'알고리즘 > 백준' 카테고리의 다른 글
[백준][C++] 1655: 가운데를 말해요 (0) | 2024.02.28 |
---|---|
[백준][C++] 19598: 최소 회의실 개수 (0) | 2024.02.27 |
[백준][C++] 15903: 카드 합체 놀이 (0) | 2024.02.22 |
[백준][C++] 10219: Meats On The Grill (0) | 2024.02.20 |
[백준][C++] 2075: N번째 큰 수 (0) | 2024.02.17 |