코딩테스트/Baekjoon Online Judge

[백준] 1260번 유기농 배추

sujin7837 2021. 7. 1. 15:44
반응형

문제

차세대 영농인 한나는 강원도 고랭지에서 유기농 배추를 재배하기로 하였다. 농약을 쓰지 않고 배추를 재배하려면 배추를 해충으로부터 보호하는 것이 중요하기 때문에, 한나는 해충 방지에 효과적인 배추흰지렁이를 구입하기로 결심한다. 이 지렁이는 배추근처에 서식하며 해충을 잡아 먹음으로써 배추를 보호한다. 특히, 어떤 배추에 배추흰지렁이가 한 마리라도 살고 있으면 이 지렁이는 인접한 다른 배추로 이동할 수 있어, 그 배추들 역시 해충으로부터 보호받을 수 있다. 한 배추의 상하좌우 네 방향에 다른 배추가 위치한 경우에 서로 인접해있는 것이다.

한나가 배추를 재배하는 땅은 고르지 못해서 배추를 군데군데 심어 놓았다. 배추들이 모여있는 곳에는 배추흰지렁이가 한 마리만 있으면 되므로 서로 인접해있는 배추들이 몇 군데에 퍼져있는지 조사하면 총 몇 마리의 지렁이가 필요한지 알 수 있다. 예를 들어 배추밭이 아래와 같이 구성되어 있으면 최소 5마리의 배추흰지렁이가 필요하다. 0은 배추가 심어져 있지 않은 땅이고, 1은 배추가 심어져 있는 땅을 나타낸다.

1 1 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 1 1 0 0 0 1 1 1
0 0 0 0 1 0 0 1 1 1

입력

입력의 첫 줄에는 테스트 케이스의 개수 T가 주어진다. 그 다음 줄부터 각각의 테스트 케이스에 대해 첫째 줄에는 배추를 심은 배추밭의 가로길이 M(1 ≤ M ≤ 50)과 세로길이 N(1 ≤ N ≤ 50), 그리고 배추가 심어져 있는 위치의 개수 K(1 ≤ K ≤ 2500)이 주어진다. 그 다음 K줄에는 배추의 위치 X(0 ≤ X ≤ M-1), Y(0 ≤ Y ≤ N-1)가 주어진다. 두 배추의 위치가 같은 경우는 없다.

출력

각 테스트 케이스에 대해 필요한 최소의 배추흰지렁이 마리 수를 출력한다.

예제 입력 1

2

10 8 17

0 0

1 0

1 1

4 2

4 3

4 5

2 4

3 4

7 4

8 4

9 4

7 5

8 5

9 5

7 6

8 6

9 6

10 10 1

5 5

예제 출력 1

5

1

예제 입력 2

1

5 3 6

0 2

1 2

2 2

3 2

4 2

4 0

예제 출력 2

2

 

소스코드

1. DFS 이용

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

int m, n;
int arr[2501][2501]={0,};
bool visit[2501][2501]={false};
int dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1};
int num=0;

void dfs(int a, int b) {
    visit[a][b]=true;
    
    for(int i=0;i<4;i++) {	//현재 땅에서 상하좌우를 탐색한다.
        int ax=a+dx[i];
        int bx=b+dy[i];
        
        if(ax>=0 && ax<m && bx>=0 && bx<n) {	//좌표값이 범위 내에 있는지 확인한다.
            if(!visit[ax][bx] && arr[ax][bx]==1) dfs(ax,bx);	//인접한 배추가 있으면 dfs를 재귀호출한다. 
        }
    }
    
}

int main() {
    int t, k;
    int x, y;
    
    
    cin>>t;
    
    for(int i=0;i<t;i++) {
        cin>>m>>n>>k;
        
        for(int i=0;i<k;i++) {
            cin>>x>>y;
            arr[x][y]=1;
        }
        for(int i=0;i<m;i++) {
            for(int j=0;j<n;j++) {
                if(!visit[i][j] && arr[i][j]==1) {	//밭을 탐색하며 배추가 심어져 있는 땅을 찾는다.
                    num++;	//찾으면 num 값을 1만큼 증가시킨다.
                    dfs(i,j);	//dfs를 통해 이동 가능한 땅을 탐색한다.
                }
            }
        }
        cout<<num<<endl;
        num=0;	//다음 test case 수행을 위해 배추흰지렁이 마리 수와 땅, 그리고 방문 이력을 초기화한다.
        memset(visit, false, sizeof(visit));
        memset(arr, 0, sizeof(arr));
    }
    
    return 0;
}

 

 

2. BFS 이용

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

int map[51][51];
int m, n, cnt=0;
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};

int bfs(int x, int y) {
    cnt++;	//bfs를 실행하면 cnt 값을 1만큼 증가시켜준다.
    map[x][y]=0;	//현재 땅을 0으로 바꿔준다.(이미 탐색했음을 나타낸다.)
    queue<pair<int, int>> q;
    q.push(make_pair(x, y));	//queue에 현재 땅을 push 한다.
    
    while(!q.empty()) {	//queue에 원소가 들어있으면 반복문을 계속 수행한다.
        int ax=q.front().first;
        int ay=q.front().second;
        q.pop();	//현재 땅을 queue에서 pop 한다.
        
        for(int i=0;i<4;i++) {	//현재 땅에서 상하좌우를 탐색한다.
            int bx=ax+dx[i];
            int by=ay+dy[i];
            
            if(bx>=0 && by>=0 && bx<m && by<n && map[bx][by]==1) {	//좌표가 땅의 범위 내에 있으면서 배추가 존재하는지 확인한다.
                map[bx][by]=0;	//탐색한 인접 땅을 0으로 바꿔준다.
                q.push(make_pair(bx, by));	//queue에 인접 땅을 push 한다.
            }
        }
    }
    return cnt;
}

int main() {
    int t, k;
    int first, second;
    
    cin>>t;
    for(int i=0;i<t;i++) {
        cin>>m>>n>>k;
        for(int j=0;j<k;j++) {
            cin>>first>>second;
            map[first][second]=1;
        }
        for(int j=0;j<m;j++) {	//땅을 탐색하며 배추가 심어진 곳을 찾는다.
            for(int k=0;k<n;k++) {
                if(map[j][k]==1) bfs(j, k);	//bfs를 이용하여 인접한 것이 있는지 탐색한다.
            }
        }
        cout<<cnt<<endl;
        cnt=0;	//다음 테스트 케이스 수행을 위해 배추흰지렁이 마리 수와 땅을 초기화한다.
        memset(map, 0, sizeof(map));
    }
    return 0;
}

 

반응형