문제 https://www.acmicpc.net/problem/4963
백준에서 그래프 탐색 알고리즘 문제를 찾아보면 같은 방법으로 풀 수 있는 유사한 문제가 많다.(2667, 1012..)
풀이
DFS를 이용하여 풀 수 있는 문제이다. 유의할 점은 상하좌우뿐만 아니라 대각선으로 연결된 것까지 인접했다고 보므로, 상하좌우, 4방향의 대각선까지 8방향을 전부 탐색해야 한다.
따라서 배열 dx 와 dy를 선언하여 각 좌표에 더해줌으로써 8방향을 전부 확인할 수 있다.
이때 탐색하려는 좌표가 map의 범위를 넘어가지 않는지를 확인해줘야 한다.
배열을 돌다가 방문하지 않았고, map의 값이 1인 좌표를 만나면 dfs를 수행한다. 이 좌표에서부터 DFS를 수행하고 함수가 종료되면 인접한 좌표를 다 탐색했다는 것이므로 cnt를 증가한다.
마지막으로 사용한 배열(visited, map)을 0으로 초기화해야 한다.
코드
#include <iostream>
using namespace std;
int w,h;
bool visited[50][50];
int map[50][50];
//상하좌우대각선 위치 좌표
int dx[8] = {0,1,0,-1,1,1,-1,-1};
int dy[8] = {-1,0,1,0,-1,1,1,-1};
void dfs(int x, int y)
{
for(int i=0; i<8; i++)
{
int rx = x+dx[i];
int ry = y+dy[i];
if(rx>=h || rx<0 || ry>=w || ry<0) continue;//map의 범위를 넘어설 경우
if(!visited[rx][ry]&&map[rx][ry]==1)
{
visited[rx][ry]=true;
dfs(rx,ry);
}
}
}
int main()
{
while(1)
{
int cnt=0;
cin>>w>>h;
if(w==0 && h==0) break;
for(int i=0; i<h; i++)
{
for(int j=0; j<w; j++)
{
int a;
cin>>a;
map[i][j]=a;
}
}
for(int i=0; i<h; i++)
{
for(int j=0; j<w; j++)
{
if(!visited[i][j]&&map[i][j]==1)
{
visited[i][j];
dfs(i,j);
cnt++;
}
}
}
for(int i=0; i<h; i++) //map과 visited 배열을 초기화
{
for(int j=0; j<w; j++)
{
visited[i][j]= false;
map[i][j]=0;
}
}
cout<<cnt<<'\n';
}
}
'알고리즘 > 문제 풀이' 카테고리의 다른 글
백준 1244 - 스위치 켜고 끄기(C++) (0) | 2022.06.21 |
---|---|
백준 2178 - 미로 탐색(C++) (0) | 2022.06.20 |
프로그래머스 - 전화번호 목록(c++) (0) | 2022.06.17 |
백준 1269 - 대칭 차집합 (0) | 2022.06.07 |
백준 9613 - GCD 합 (0) | 2022.06.05 |