티스토리 뷰
문제 링크 : https://www.acmicpc.net/problem/10026
문제
적록색약은 빨간색과 초록색의 차이를 거의 느끼지 못한다. 따라서, 적록색약인 사람이 보는 그림은 아닌 사람이 보는 그림과는 좀 다를 수 있다.
크기가 N×N인 그리드의 각 칸에 R(빨강), G(초록), B(파랑) 중 하나를 색칠한 그림이 있다. 그림은 몇 개의 구역으로 나뉘어져 있는데, 구역은 같은 색으로 이루어져 있다. 또, 같은 색상이 상하좌우로 인접해 있는 경우에 두 글자는 같은 구역에 속한다. (색상의 차이를 거의 느끼지 못하는 경우도 같은 색상이라 한다)
예를 들어, 그림이 아래와 같은 경우에
적록색약이 아닌 사람이 봤을 때 구역의 수는 총 4개이다. (빨강 2, 파랑 1, 초록 1) 하지만, 적록색약인 사람은 구역을 3개 볼 수 있다. (빨강-초록 2, 파랑 1)
그림이 입력으로 주어졌을 때, 적록색약인 사람이 봤을 때와 아닌 사람이 봤을 때 구역의 수를 구하는 프로그램을 작성하시오.
입력
첫째 줄에 N이 주어진다. (1 ≤ N ≤ 100)
둘째 줄부터 N개 줄에는 그림이 주어진다.
출력
적록색약이 아닌 사람이 봤을 때의 구역의 개수와 적록색약인 사람이 봤을 때의 구역의 수를 공백으로 구분해 출력한다.
풀이
DFS 와 BFS로 모두 풀이가 가능한 문제이다. 적록색약인 사람 입장에서의 맵을 새로 그ᄅ면 쉽다. R과 G를 하나로 통일시켜주는 것이다. 배열을 순회하면서 동서남북에서 자기와 똑같은 색을 가진 배열이면 visit 체크를 해주는 식으로 해서 풀어주었다. 탐색 함수를 하나 더 만들어 주기 귀찮아서 배열을 매개변수로 해서 넘겨주었다.
적록색약 이 아닌 함수를 체크 하고 나서 적록색약인 사람도 체크해주어야 하므로 vistit 배열 초기화와 cnt 초기화를 잊지 말자.
DFS
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
|
#include<iostream>
#include<cstring>
using namespace std;
int N;
char map[101][101];
char sick[101][101];
int visited[101][101];
int vetx[] ={ 1, 0 , -1, 0};
int vety[] = {0 ,1, 0 , -1};
int cnt = 0 ;
void dfs(int y , int x , char s , char (*a)[101])
{
int i;
int cury = y , curx = x;
for( i = 0 ; i<4; i++)
{
int nextx = curx + vetx[i];
int nexty = cury + vety[i];
if(nextx >= 1 && nextx <=N && nexty >=1 && nexty<=N)
{
if(a[nexty][nextx] == s && visited[nexty][nextx]==0 )
{
visited[nexty][nextx] = 1 ;
dfs(nexty,nextx, s , a) ;
}
}
}
}
int main()
{
int i,j;
cin >> N;
for( i = 1 ; i<= N ; i++)
for( j = 1 ; j<= N ; j++)
{
cin >> map[i][j];
if(map[i][j] == 'G' || map[i][j] == 'R')
sick[i][j] ='R';
else
sick[i][j] = map[i][j];
}
for( i = 1 ; i<= N ; i++)
for( j = 1 ; j<= N ; j++)
{
if( visited[i][j] ) continue;
dfs(i , j , map[i][j] , map );
cnt++;
}
cout << cnt <<" ";
memset(visited,0,sizeof(visited));
cnt = 0 ;
for( i = 1 ; i<= N ; i++)
for( j = 1 ; j<= N ; j++)
{
if( visited[i][j] ) continue;
dfs(i , j , sick[i][j] , sick );
cnt++;
}
cout << cnt <<" ";
return 0;
}
|
cs |
BFS
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
|
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//R은 2 G는 3 B 는 4로 표하자 <--정상인
//R,G 를 5로 B 는 4로 표하자 <--적록색약
int N;
int Map[101][101]; //map 은 정상인의 입장과동일
int Colorweek[101][101]; // 적록색약 입장
int visit[101][101];
int front,rear;
int gneralcnt;
int colorcnt;
int VetY[]={0,0,1,-1};
int VetX[]={1,-1,0,0};
typedef struct q{
int y,x;
}q;
q queue[101*101];
void enque(int y, int x)
{
q temp;
temp.y=y;
temp.x=x;
queue[rear++]=temp;
}
q deque()
{
return queue[front++];
}
void BFS(int (*a)[101])
{
int nextY,nextX,i;
while(rear!=front)
{
q pop=deque();
for(i=0;i<4;i++)
{
nextY = pop.y + VetY[i];
nextX = pop.x + VetX[i];
if(nextY>=0 && nextY<N && nextX>=0 && nextX<N )
{
if(visit[nextY][nextX]==0)
{
if(a[nextY][nextX]==a[pop.y][pop.x])
{
visit[nextY][nextX]=1;
enque(nextY, nextX);
}
}
}
}
}
}
//R은 2 G는 3 B 는 4로 표하자 <--정상인
//R,G 를 5로 B 는 4로 표하자 <--적록색약
void ColorStance(int (*a)[101]) //적록색약 입장에서의 모습
{
int i,j;
for(i=0;i<N;i++)
for(j=0;j<N;j++)
{
if(a[i][j]==2 || a[i][j]==3)
Colorweek[i][j]=5;
else
Colorweek[i][j]=4;
}
}
int main()
{
int i,j;
scanf("%d",&N);// N이 주어진다. (1 ≤ N ≤ 100)
for(i=0;i<N;i++){
char *s=calloc(N+1,sizeof(char));
scanf("%s",s);
int cnt=0;
while(s[cnt]!='\0')
{
if(s[cnt]=='R')
Map[i][cnt++]=2;
else if(s[cnt]=='G')
Map[i][cnt++]=3;
else if(s[cnt]=='B')
Map[i][cnt++]=4;
}
free(s);
}
ColorStance(Map);//적록색약인 사람입장에서 볼때.
for(i=0;i<N;i++)
for(j=0;j<N;j++)
if(visit[i][j]==0)
{
visit[i][j]=1;
enque(i,j);
BFS(Map);
gneralcnt++;
front=rear=0;
}
memset(visit,0, sizeof(visit));
for(i=0;i<N;i++)
for(j=0;j<N;j++)
if(visit[i][j]==0)
{
visit[i][j]=1;
enque(i,j);
BFS(Colorweek);
colorcnt++;
front=rear=0;
}
printf("%d %d\n",gneralcnt,colorcnt);
return 0;
}
|
cs |
'백준 (BOJ) > DFS' 카테고리의 다른 글
백준)11724-연결 요소의 개수 (0) | 2019.05.11 |
---|---|
백준)9446-텀 프로젝트 (0) | 2019.05.08 |
백준)2668-숫자고르기 (0) | 2019.05.08 |
백준) 9205 맥주 마시면서 걸어가기 (0) | 2019.05.04 |
백준) 1325 - 효율적인 해킹 (0) | 2019.05.03 |
- Total
- Today
- Yesterday
- 사이크
- 이분 매칭
- 그리디알고리즘
- 플로이드
- 이분매칭
- CSS
- #스페인어 #스페인어인강 #스페인어공부 #시원스쿨스페인어
- greedy
- php
- 그리디
- JavaSwing
- BFS
- 그래프
- A
- 라오킹전사
- stri
- 라이즈오브킹덤즈
- HTML
- KVK4
- 백트래킹
- dfs
- 백트레킹
- 다익스트라
- 정렬
- 사이클
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |