티스토리 뷰

문제

<2667: 단지번호 붙이기>

문제 링크: https://www.acmicpc.net/problem/2667


<4963: 섬의 개수>

문제 링크: https://www.acmicpc.net/problem/4963

위 두 문제는 해결하는데 있어 많이 유사하기 때문에 같이 포스팅을 하게되었습니다.


두 문제 전부 DFS 혹은 BFS를 사용하여 해결 할 수 있습니다.


저의 경우는 DFS 방법으로 문제를 해결하였습니다.


문제 푸는데 있어 핵심은 움직임에 있습니다. 


2667번의 경우, 상·하··로만 움직일 수 있습니다. 따라서 움직일 수 있는 방향을 먼저 지정을 해주어야 합니다.

4963번의 경우에는 상···우 뿐만아니라 대각선까지 움직일 수 있습니다. 8개의 방향 모두 지정해주어야 합니다.


또, 중요한 것은 주어진 지도를 벗어나면 안된다는 것입니다. 범위를 주어 지도를 벗어나지 않도록 해주어야 합니다.


4963번의 경우, 실수할 수 있는 부분은 지도를 지정할 때나 움직일때, 행과 열을 잘 지정해주어야 합니다. 

2667번은 정사각형이기 때문에 모르고 넘어가도 상관이 없지만, 4963번의 지도는 행과 열이 다를 수 있기 때문에 잘 지정해 주어야 합니다.

이중 for문을 사용하였을 때, 순서가 중요하기때문에 이를 바꾸었을 시에 답이 이상하게 나올 수 있습니다.


저도 이부분에서 실수를 하여 조금 시간이 걸렸습니다;;;;

코드

<2667: 단지번호 붙이기>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <cstdio>
#include <algorithm>
using namespace std;
int a[30][30];
int d[30][30];
int dx[] = {0,0,1,-1};  //움직이는 방향
int dy[] = {1,-1,0,0};  //상,하,우,좌 순서
int n;
int ans[25*25];
void dfs(int x, int y, int cnt) {
    d[x][y] = cnt;
    //4방향으로 움직여야 하기 때문에 포문을 써서 함.
    for (int k=0; k<4; k++) {
        int nx = x+dx[k];
        int ny = y+dy[k];
        //움직였을 때, 범위를 벗어나면 안된다.(움직임은 맵 상에서만.)
        if (0 <= nx && nx < n && 0 <= ny && ny < n) {
            //맵에서 1로 표시되어있어야하며, 방문했던 곳인지 확인.
            if (a[nx][ny] == 1 && d[nx][ny] == 0) {
                dfs(nx, ny, cnt);
            }
        }
    }
}
int main() {
    scanf("%d",&n);
    //지도 입력 받기
    for (int i=0; i<n; i++) {
        for (int j=0; j<n; j++) {
            scanf("%1d",&a[i][j]);
        }
    }
    int cnt = 0;
    for (int i=0; i<n; i++) {
        for (int j=0; j<n; j++) {
            if (a[i][j] == 1 && d[i][j] == 0) {
                dfs(i, j, ++cnt);
            }
        }
    }
    printf("%d\n",cnt);
    for (int i=0; i<n; i++) {
        for (int j=0; j<n; j++) {
            ans[d[i][j]]+=1;
        }
    }
    sort(ans+1, ans+cnt+1);
    for (int i=1; i<=cnt; i++) {
        printf("%d\n",ans[i]);
    }
    return 0;
}
cs

<4963: 섬의 개수>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
using namespace std;
 
int map[51][51];    //지도를 할당.
int isLand[51][51]; //땅인지 확인.
int dx[] = {-1,0,1,-1,1,-1,0,1};    //움직임 8방향(대각선 포함).
int dy[] = {1,1,1,0,0,-1,-1,-1};    //좌상, 상, 우상, 좌, 우, 좌하, 하, 우하
int w,h;
 
void dfs(int x, int y, int key){
    isLand[x][y]=1;
    for(int i=0; i<8; i++){
        int nx = x+dx[i];
        int ny = y+dy[i];
        if(0<=nx && nx<&& 0<=ny && ny<w){
            if(map[nx][ny]==1 && isLand[nx][ny]==0){
                dfs(nx,ny,key);
            }
        }
    }
}
 
int main(){
    while(true)
    {
        cin >> w >> h;
        if(w==0 && h==0) break;
        
        //행과 열 순서 중요!!
        for(int i=0; i<h; i++){
            for(int j=0; j<w; j++){
                cin >> map[i][j];
                isLand[i][j] = 0;
            }
        }
        int key=0;
        for(int i=0; i<h; i++){
            for(int j=0; j<w; j++){
                if(map[i][j]==1 && isLand[i][j]==0){
                    dfs(i,j,++key);
                }
            }
        }
        cout << key<<"\n";
    }
    return 0;
}
 
cs


'알고리즘 문제 풀이 > BOJ' 카테고리의 다른 글

백준 14501: 퇴사  (2) 2018.01.19
백준 14502: 연구소  (6) 2018.01.18
백준 1707: 이분 그래프  (0) 2018.01.10
백준 11052: 붕어빵 판매하기  (0) 2018.01.06
백준 1463: 1로 만들기  (0) 2018.01.05
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함