참고한 글
https://yabmoons.tistory.com/64
[ 백준 3197 ] 백조의 호수 (C++)
백준의 백조의 호수(3197) 문제이다. ( 문제 바로가기 ) [ 문제풀이 ] 1. 물과 빙판과 백조 3개로 이루어진 맵이 주어진다. 백조가 서로 만나기 위해서는 사이에 빙판이 있으면 안되고, 물이 있어아
yabmoons.tistory.com
중요 지식
BFS - 백조가 어디있는지 알아낸다.
queue - 물을 넣는다.
코드
#include <iostream>
#include <vector>
#include <string>
#include <queue>
using namespace std;
const int MAX = 1500;
typedef struct {
int y, x;
} Dir;
Dir moveDir[4] = { {1, 0}, {-1, 0}, {0, 1}, {0, -1} };
int R, C; string lake[MAX];
int main(void) {
ios_base::sync_with_stdio(0);
cin.tie(0);
cin >> R >> C;
vector<pair<int, int>> swan;
queue<pair<int, int>> waterQ;
for (int i = 0; i < R; i++)
{
cin >> lake[i];
for (int j = 0; j < C; j++)
{
if (lake[i][j] == 'L')
{
swan.push_back({i, j});
}
if (lake[i][j] == '.' || lake[i][j] == 'L')
{
waterQ.push({i, j});
}
}
}
queue<pair<int, int>> q;
q.push(swan[0]);
bool visited[MAX][MAX] = { false, };
visited[swan[0].first][swan[0].second] = true;
int day = 0;
while (1)
{
queue<pair<int, int>> nextQ;
bool flag = false;
while (!q.empty())
{
int y = q.front().first;
int x = q.front().second;
q.pop();
if (y == swan[1].first && x == swan[1].second) {
flag = true;
break;
}
for (int i = 0; i < 4; i++) {
int nextY = y + moveDir[i].y;
int nextX = x + moveDir[i].x;
if (nextY < 0 || nextY >= R || nextX < 0 || nextX >= C || visited[nextY][nextX])
continue;
visited[nextY][nextX] = true; // 물에 인접한 얼음이므로 다음 날에 백조가 탐색할 곳이므로 nextQ에 넣어준다
if (lake[nextY][nextX] == 'X') {
nextQ.push({nextY, nextX});
continue;
}
q.push({nextY, nextX});
}
}
if (flag)
break;
q = nextQ; // 얼음을 녹이는 과정
int waterQSize = waterQ.size();
while (waterQSize--) {
int y = waterQ.front().first;
int x = waterQ.front().second;
waterQ.pop();
for (int i = 0; i < 4; i++) {
int nextY = y + moveDir[i].y;
int nextX = x + moveDir[i].x;
if (nextY < 0 || nextY >= R || nextX < 0 || nextX >= C) {
continue;
}
if (lake[nextY][nextX] == 'X') {
lake[nextY][nextX] = '.';
waterQ.push({nextY, nextX});
}
}
}
day++;
}
cout << day << "\n";
return 0;
}
풀이
궁금한 것이 한두가지가 아니라 차근차근 알아내보자
Q. bfs를 사용한 이유
A.
Q. waterQ의 의미
A.
아래는 직접 쓴 실패한 코드이다
탐색 알고리즘이라곤 아는게 DFS와 BFS이고 백트래킹은 쓸 수 없을거 같아 DFS만으로 썼다 하지만 시간초과로 실패했다
더보기
#include <iostream>
using namespace std;
int R, C;
char map[1501][1501];
int v[1501][1501];
int duckV[1501][1501];
int dx, dy;
int duckCount = 0;
int rd[4] = {0, 1, 0, -1};
int cd[4] = {1, 0, -1, 0};
void initDuckV(){
for(int i = 0; i < R; i++){
for(int j = 0; j < C; j++){
duckV[i][j] = 0;
}
}
}
void initV(){
for(int i = 0; i < R; i++){
for(int j = 0; j < C; j++){
v[i][j] = 0;
}
}
}
void nextDay(int r, int c){
for(int i = 0; i < R; i++){
for(int j = 0; j < C; j++){
if(map[i][j] == 'X') v[i][j] = 1; // 빙하 체크
for(int k = 0; k < 4; k++){
int x = i + rd[k];
int y = j + cd[k];
if((x < 0 || x >= R) || (y < 0 || y >= C))
continue;
if(map[i][j] == 'X' && map[x][y] == '.' && v[x][y] != 1) // 자신이 빙하이고, 주위에 물이 있다해도 오늘 물로 변한 빙하엔 상호작용하지 않는다
map[i][j] = '.';
}
}
}
}
void duckDFS(int r, int c){
if(duckV[r][c] || map[r][c] == 'X') return;
duckV[r][c] = 1;
if(map[r][c] == 'L') duckCount++;
for(int i = 0; i < 4; i++){
int x = r + rd[i];
int y = c + cd[i];
if((x < 0 || x >= R) || (y < 0 || y >= C))
continue;
duckDFS(x, y);
}
}
void printMap(){
printf("\n 맵 출력=======================\n");
for(int i = 0; i < R; i++){
for(int j = 0; j < C; j++){
printf("%c ", map[i][j]);
if(map[i][j] == 'L'){
dx = i;
dy = j;
}
}
printf("\n");
}
}
int main(){
ios_base :: sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int day = 0;
cin >> R >> C;
for(int i = 0; i < R; i++){
for(int j = 0; j < C; j++){
cin >> map[i][j];
}
}
duckDFS(dx, dy);
while(duckCount != 2){
day++;
duckCount = 0;
initV();
initDuckV();
nextDay(0, 0);
// printMap(); 간편 디버깅
duckDFS(dx, dy);
}
cout << day;
return 0;
}
'프로그래밍 문제집 > 백준' 카테고리의 다른 글
1655번-가운데를 말해요 (0) | 2022.03.11 |
---|---|
[KOI 2021 1차대회 중등부] 21758번-꿀 따기 (0) | 2022.03.08 |
9663번-N-Queen (0) | 2022.02.28 |
15649번-N과 M (1) (0) | 2022.02.27 |
[KOI 2020 1차대회 중등부] 19942번-다이어트 (0) | 2022.02.27 |