문제 링크
문제를 풀고 나서 생각해보니 연합을 만들 때 DFS/BFS 어느 방법으로 해도 상관없을것 같다. 나는 DFS를 사용하였다.
side case에 걸리지 않고 한번에 통과해서 기분좋았던 문제였다. ㅎㅎ
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
|
#include <iostream>
#include <cmath>
using namespace std;
int N,L,R,ans=0,sum,cnt,pos=1;
int map[51][51],tmap[51][51],visited[51][51],zero[51][51];
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
void map_copy(int (*a)[51],int (*b)[51]){
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
a[i][j]=b[i][j];
}
void dfs(int x,int y){
for(int i=0;i<4;i++)
for(int j=0;j<4;j++){
int nx=x+dx[i],ny=y+dy[i];
if(nx<0||ny<0||nx>N-1||ny>N-1)continue;
if(abs(map[x][y]-map[nx][ny])>=L&&abs(map[x][y]-map[nx][ny])<=R&&!visited[nx][ny]){
visited[nx][ny]=pos;dfs(nx,ny);}
}
}
void move(){
sum=0;cnt=0;
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
if(visited[i][j]==pos){sum+=map[i][j];cnt++;}
sum/=cnt;
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
if(visited[i][j]==pos)tmap[i][j]=sum;
pos++;
}
void make_union(){
for(int x=0;x<N;x++){
for(int y=0;y<N;y++){
for(int i=0;i<4;i++)
for(int j=0;j<4;j++){
int nx=x+dx[i],ny=y+dy[i];
if(nx<0||ny<0||nx>N-1||ny>N-1)continue;
if(abs(map[x][y]-map[nx][ny])>=L&&abs(map[x][y]-map[nx][ny])<=R&&!visited[x][y]){
visited[x][y]=pos;
dfs(x,y);
move();
}
}
}
}
}
bool end(){
for(int x=0;x<N;x++){
for(int y=0;y<N;y++){
for(int i=0;i<4;i++)
for(int j=0;j<4;j++){
int nx=x+dx[i],ny=y+dy[i];
if(nx<0||ny<0||nx>N-1||ny>N-1)continue;
if(abs(map[x][y]-map[nx][ny])>=L&&abs(map[x][y]-map[nx][ny])<=R){
return true;
}
}
}
}
return false;
}
void solve(){
map_copy(tmap,map);
while(end()){
map_copy(visited,zero);
make_union();
map_copy(map,tmap);
pos=1;ans++;
}
cout<<ans;
}
main(){
ios::sync_with_stdio(0);
cout.tie(NULL);
cin.tie(NULL);
cin>>N>>L>>R;
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
cin>>map[i][j];
solve();
}
|
cs |
입력을 받은 후에 함수를 5개 만들었다.
- map의 상태를 초기화 시켜주거나 복사해주는 map_copy함수
- 현재의 map의 인구상태를 기준으로 연합을 만드는 make_union함수
- 연합을 만들 때 사용하는 dfs함수
- 연합을 만들고 이동한 후의 상태를 나타내는 move함수
여기서 주의할 부분이 이동한 후의 상태는 map에 넣지 않고 tmap에 넣었다.
왜냐하면 인구는 현재 상태를 기준으로 모든 연합이 동시에 이동하기 때문이다.
개별적으로 이동하면 연합을 다시 만들때 영향이 미쳐 오류가 발생한다.
- 종료할 조건인지 판별하는 end 함수를 만들어 while문이 빠져나온다면 정답을 출력하게 하였다.
pos 변수는 각 연합을 구분짓게 해 dfs를 할 경우 방문체크의 역할도 담당한다.
'Algorithm > 문제 풀이 (Problem Solving)' 카테고리의 다른 글
[C++] 코드그라운드 연습문제 프로그래밍 경진대회 문제풀이 (0) | 2019.06.19 |
---|---|
[C++,구현,BFS,DFS] 백준 15686번 치킨 배달 문제풀이 (0) | 2019.05.25 |
[C++,구현] 백준 17143번 낚시왕 문제풀이 (0) | 2019.04.28 |
[C++,구현] 백준 17144번 미세먼지 안녕! 문제풀이 (0) | 2019.04.25 |
[C++,구현] 백준 14890번 경사로 문제풀이 (0) | 2019.04.06 |
댓글