반응형

문제 출처 :


https://www.acmicpc.net/problem/2573



알고리즘 분석 :


문제 해결에 필요한 사항

1. BFS

2. 시뮬레이션


이 문제는 BFS가 핵심이긴 하지만, 거의 시뮬레이션에 가까운 것 같다.


요구하는 사항이 너무 많은 문제여서 좋으면 좋은 문제라고 할 수 있고, 너무 귀찮으면 귀찮은 문제라 할 수 있을 듯 하다.



빙산을 녹이는 기준은 바다가 있는 곳을 기준으로 사방향에 아직 빙산이 있다면 녹여주고,


그 녹았는 빙산이 0이될 경우 다음 빙산에 영향을 주면 안되기에 visit 배열로 그것을 막아준다.(동시에 모두 녹도록 만들어 준다.)



빙산 그룹을 확인하는 방법은 그냥 bfs를 2중 포문속에서 돌며 그룹을 지어주어 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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#include <iostream>
#include <cstdio>
#include <queue>
#include <memory.h>
 
using namespace std;
 
typedef pair<intint> pii;
int map[302][302];
int ans[302][302];
 
int visit[302][302];
 
int dy[4= { -1,1,0,};
int dx[4= { 0,0,-1,};
int total;
 
int main()
{
    int n, m;
    scanf("%d %d"&n, &m);
 
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
        {
            scanf("%d"&map[i][j]);
            total += map[i][j];
        }
 
    int cnt = 1;
    int visitCnt = 1;
    int time = 0;
 
    bool finish = false;
 
    // 빙산 그룹 확인(처음부터 2그룹인지)
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            if (map[i][j] && ans[i][j] == 0)
            {
                queue<pii> q;
 
                q.push({ i,j });
 
                while (!q.empty())
                {
                    int y = q.front().first;
                    int x = q.front().second;
 
                    q.pop();
 
                    if (ans[y][x])
                        continue;
 
                    ans[y][x] = cnt;
 
                    for (int k = 0; k < 4; k++)
                    {
                        int hereY = y + dy[k];
                        int hereX = x + dx[k];
 
                        if (hereY >= n || hereY < || hereX >= m || hereX < || !map[hereY][hereX])
                            continue;
 
                        q.push({ hereY, hereX });
                    }
                }
                cnt++;
 
                if (cnt == 3)
                {
                    printf("0");
                    return 0;
                }
            }
    
 
    while (!finish)
    {
        // 처음 빙산 시작 위치 파악
        memset(ans, 0sizeof(ans));
        cnt = 1;
 
        // 빙산 녹이기
        for(int i = 0; i < n; i ++)
            for(int j = 0; j < m; j ++)
                if (map[i][j] == && visit[i][j] != visitCnt)
                {
                    for (int k = 0; k < 4; k++)
                    {
                        int hereI = i + dy[k];
                        int hereJ = j + dx[k];
 
                        if (map[hereI][hereJ])
                        {
                            map[hereI][hereJ]--;
                            visit[hereI][hereJ] = visitCnt;
                            total--;
                        }
                    }
                }
 
        // 빙산이 다녹아버렸으면
        if (total == 0)
        {
            printf("0");
            return 0;
        }
 
        visitCnt++;
 
 
        // 빙산 그룹 확인
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++)
                if (map[i][j] && ans[i][j] == 0)
                {
                    queue<pii> q;
 
                    q.push({ i,j });
 
                    while (!q.empty())
                    {
                        int y = q.front().first;
                        int x = q.front().second;
 
                        q.pop();
 
                        if (ans[y][x])
                            continue;
 
                        ans[y][x] = cnt;
 
                        for (int k = 0; k < 4; k++)
                        {
                            int hereY = y + dy[k];
                            int hereX = x + dx[k];
 
                            if (hereY >= n || hereY < || hereX >= m || hereX < || !map[hereY][hereX])
                                continue;
 
                            q.push({ hereY, hereX });
                        }
                    }
                    cnt++;
 
                    // 빙산이 2그룹으로 나뉘었다면
                    if (cnt == 3)
                        finish = true;
                }
 
        time++;            
    }
    
    cout << time << endl;
    return 0;
}
 
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus


반응형

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

[1671번] 상어의 저녁식사  (0) 2017.04.14
[9576번] 책 나눠주기  (0) 2017.04.14
[1600번] 말이 되고픈 원숭이  (0) 2017.04.14
[11812번] K진 트리  (0) 2017.04.13
[5639번] 이진 검색 트리  (0) 2017.04.13