2023. 9. 20. 13:38, 알고리즘/BOJ
https://www.acmicpc.net/problem/10026
#include <bits/stdc++.h>
using namespace std;
string str;
int n;
char board[105][105];
int vis[105][105];
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
int bfs(char c){
int cnt=0;
for(int i=0; i<105;i++)
fill(vis[i],vis[i]+105,0);
queue<pair<int,int>> Q;
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
if(board[i][j]!=c) continue;
if(vis[i][j]==1) continue;
vis[i][j]=1;
Q.push({i,j});
cnt++;
while(!Q.empty()){
auto cur=Q.front(); Q.pop();
// cnt++;
for(int dir=0; dir<4; dir++){
int nx=cur.first+dx[dir];
int ny=cur.second+dy[dir];
if(nx<0||nx>=n||ny<0||ny>=n) continue;
if(board[nx][ny]!=c) continue;
if(vis[nx][ny]==1) continue;
vis[nx][ny]=1;
Q.push({nx,ny});
}
}
}
}
return cnt;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cin>>n;
for(int i =0; i<n; i++){
cin>>str;
for(int j=0; j<n; j++){
board[i][j]=str[j];
}
}
cout<<bfs('R')+bfs('G')+bfs('B')<<' ';
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
if(board[i][j]=='G') board[i][j]='R';
}
}
cout<<bfs('R')+bfs('B');
}
위에 있는 내가 제출한 풀이의 경우는, 각각의 R, G, B 일때의 경우의 수들을 따로따로 나타낼 수 있도록 만든 풀이인데, 다른 풀이를 보다보니 이런식으로 해결하지 않고, 그냥 한번에 구분지어저 있는 영역들의 갯수를 바로 출력하도록 하는 풀이를 볼 수 있었다.
// Authored by : seeys
// Co-authored by : BaaaaaaaaaaarkingDog
// http://boj.kr/99a676d859f54fa0944f81f94ade04a3
#include <bits/stdc++.h>
using namespace std;
#define X first
#define Y second
char board[101][101];
bool vis[101][101];
int n;
int dx[4] = { 1,0,-1,0 };
int dy[4] = { 0,1,0,-1 };
void bfs(int i, int j) {
queue<pair<int, int>> Q;
Q.push({ i,j });
vis[i][j] = 1;
while (!Q.empty()) {
auto cur = Q.front(); Q.pop();
for (int dir = 0; dir < 4; dir++) {
int nx = cur.X + dx[dir];
int ny = cur.Y + dy[dir];
if (nx < 0 || nx >= n || ny < 0 || ny >= n) continue;
if (vis[nx][ny] == 1 || board[i][j] != board[nx][ny]) continue;
vis[nx][ny] = 1;
Q.push({ nx,ny });
}
}
}
int area(){
int cnt = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (!vis[i][j]) {
cnt++;
bfs(i, j);
}
}
}
return cnt;
}
int main(void) {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> board[i][j];
}
}
int not_g = area(); //적록색약이 아닌사람
// 적록색약인 사람을 구하기위한 방문배열 초기화
for(int i = 0; i < n; i++)
fill(vis[i], vis[i]+n, false);
// 적록색약은 초록과 빨강을 구분 못하므로 초록이면 빨강으로 바꿔줌
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (board[i][j] == 'G')
board[i][j] = 'R';
}
}
int is_g = area(); //적록색약인 사람
cout << not_g << " " << is_g;
return 0;
}
이 풀이에서는 if(board[i][j]!=board[nx][ny]) continue; 라는 조건으로 bfs를 돌려서, 해당 함수를 통해서 한번에 다른 영역들에 대해서 bfs를 돌면서, 해당 영역이 주변에 있는 영역들과 다른 영역이라면 cnt++ 을 시켜주어서 R 로 이루어져있던, G로 이루어져 있던, B로 이루어져 있던 모두 cnt++ 가 되도록 해서 영역들에 대해서 딱 영역이 다른 부분들에 대해 판별해줄 수 있는 함수를 작성했다.
이런 식의 풀이가 문제가 요구하는 사항에 확실하게 군더더기 없이 부합하는 풀이일 수 있겠다는 생각이 든다.
또한 문제에서 입력으로 주어지는 값에서,
5
RRRBB
GGBBB
BBBRR
BBRRR
RRRRR
위에서 볼 수 있는 바와 같이, 모두 붙어있는 형태로 주어지는데, 이렇게 붙어있는 경우 string으로 받아야 한다고 생각했는데, 다른 사람의 풀이에서 볼 수 있듯이 다 붙어 있더라도 char로 선언되어 있는 배열에 각각 하나의 요소씩 받아서 값들을 대입해줄 수 있다는 것을 알고 있으면 다음에 이런식으로도 board 를 초기화 해줄 수 있을것 같다. 물론 내가 수행한 방식처럼 하더라도 문제될것 없다.
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> board[i][j];
}
}
'알고리즘 > BOJ' 카테고리의 다른 글
BOJ 2583 c++ 영역 구하기 (0) | 2023.09.22 |
---|---|
BOJ 7569 c++ 토마토 - tuple에서 개별 원소 접근은 get<index>(tuple_name) 을 이용. 혹은 tie를 사용하자. (0) | 2023.09.21 |
BOJ 1012 유기농 배추 || x 좌표와 y 좌표의 꼬임을 매우매우 조심할것. (0) | 2023.09.16 |
BOJ 7576 토마토 || 내 풀이와 거기에서 더 좋은 개선사항. (0) | 2023.09.16 |
boj 11003 최솟값 찾기 || deque를 이용한 풀이에 대해서. (0) | 2023.09.10 |
Comments, Trackbacks