How We Coding

Week 1 - DFS

Tutoring/PS2018. 2. 20. 00:24

< 180219 >


Week 1 - DFS 


[BOJ/2667] 단지번호 붙이기 (http://boj.kr/2667)


1)


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
53
54
55
56
57
58
59
60
61
#include <cstdio>
#include <algorithm>
 
#define N 101
int n, cnt, a[N][N], s[N];
 
bool safe(int x, int y)
{
    return (0 <= x && x < n) && (0<= y && y < n);
}
 
bool cmp(int a, int b)
{
    return a < b;
}
 
void dfs(int x, int y, int k)
{
    int i, dx[] = {10-10}, dy[] = {010-1};
    a[x][y] = k;
    for(i=0; i<4; i++)
        if(safe(x+dx[i], y+dy[i]) && a[x+dx[i]][y+dy[i]]==1 )
            dfs(x+dx[i], y+dy[i], k);
}    
 
void solve(void)
{
    int i, j;
    for(i=0; i<n; i++)
        for(j=0; j<n; j++)
            if(a[i][j] == 1)
            {
                cnt++;
                dfs(i, j, cnt+1);
            }
 
    for(i=0; i<n; i++)
        for(j=0; j<n; j++)
            if(a[i][j])
                s[a[i][j]-2]++;
 
    std::sort(s, s+cnt, cmp);
}
 
int main(void)
{
    int i, j;
    scanf("%d"&n);
 
    for(i=0; i<n; i++)
        for(j=0; j<n; j++)
            scanf("%1d"&a[i][j]);
 
    solve();
 
    printf("%d\n", cnt);
    for(i=0; i<cnt; i++)
        printf("%d\n", s[i]);
 
    return 0;
}
cs





2) 이런식으로도 구현할 수 있다.


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
53
54
55
56
57
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
 
int n, cnt, a[101][101];
vector<int> v;
 
bool safe(int x, int y)
{
    return (0 <= x && x < n) && (0<= y && y < n);
}
 
int dfs(int x, int y)
{
    int i, dx[] = {10-10}, dy[] = {010-1};
    int ret = 1;
    a[x][y] = 0;
    for(i=0; i<4; i++)
        if(safe(x+dx[i], y+dy[i]) && a[x+dx[i]][y+dy[i]]==1 )
            ret += dfs(x+dx[i], y+dy[i]);
    return ret;
}    
 
void solve(void)
{
    int i, j;
    for(i=0; i<n; i++) {
        for(j=0; j<n; j++) {
            if(a[i][j] == 1)
            {
                cnt++;
                v.push_back(dfs(i, j));
            }
        }
    }
 
    sort(v.begin(), v.end());
}
 
int main(void)
{
    int i, j;
    scanf("%d"&n);
 
    for(i=0; i<n; i++)
        for(j=0; j<n; j++)
            scanf("%1d"&a[i][j]);
 
    solve();
 
    printf("%d\n", cnt);
    for(i=0; i<cnt; i++)
        printf("%d\n", v[i]);
 
}
 
cs


>> dfs() 의 리턴형이 int 이다. 결국 dfs() 호출된 횟수를 리턴하게 된다.

>> vector 를 사용했다.



[BOJ/1012] 유기농 배추 (http://boj.kr/1012)


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
53
54
#include <stdio.h>
 
int r, c;
int g[51][51];
int dr[]={10-10};
int dc[]={010-1};
 
int safe(int i, int j)
{
    return (0 <= i && i < r) && (0 <= j && j < c);
}
 
void dfs(int r, int c)
{
    int k;
    g[r][c] = 0;
 
    for(k=0; k<4; k++) {
        int nr = r + dr[k];
        int nc = c + dc[k];
        if(safe(nr, nc) && g[nr][nc])
            dfs(nr, nc);
    }
 
}
 
int main()
{
    int tc;
    scanf("%d"&tc);
    
    while(tc--) {
        int i, j, k;
        int ans = 0;
        scanf("%d%d%d"&r, &c, &k);
    
        while(k--) {
            int a, b;
            scanf("%d%d"&a, &b);
            g[a][b] = 1;
        }
                
        for(i=0; i<r; i++) {
            for(j=0; j<c; j++) {
                if(g[i][j]) {
                    ans++;
                    dfs(i, j);
                }
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}
cs


>> 16 : 방문체크 배열을 따로 안만들고, 방문한곳을 0으로 바꿔줌으로써 다시 방문할 수 없도록 하였다.



[BOJ/4963] 섬의 개수 (http://boj.kr/2963)


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
#include <stdio.h>
 
int r, c;
int g[51][51];
int di[]={-1-1-100111};
int dj[]={-101-11-101};
 
int safe(int i, int j)
{
    return (0 <= i && i < r) && (0 <= j && j < c);
}
 
void dfs(int i, int j)
{
    int k;
    g[i][j] = 0;
 
    for(k=0; k<8; k++) {
        int ni = i+di[k];
        int nj = j+dj[k];
        if(safe(ni, nj) && g[ni][nj])
            dfs(ni, nj);
    }
}
 
int main()
{
    while(1) {
        int i, j;
        int ans=0;
        scanf("%d%d"&c, &r);
 
        if(!&& !c) break;
        
        for(i=0; i<r; i++)
            for(j=0; j<c; j++)
                scanf("%d"&g[i][j]);
 
        for(i=0; i<r; i++) {
            for(j=0; j<c; j++) {
                if(g[i][j]) {
                    ans++;
                    dfs(i, j);
                }
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}
cs


>> 위와 같은 유형의 문제. 차이점이라면 8방탐색..!!

'Tutoring > PS' 카테고리의 다른 글

Week 6 - BFS (숨박꼭질)  (0) 2018.03.30
Week 5 - BFS  (0) 2018.03.24
Week 4 - BFS  (0) 2018.03.11
Week3 - DFS  (0) 2018.03.07
Week 2 - DFS  (0) 2018.02.21