프로그래밍/알고리즘
Softeer-연습문제-GINI야 도와줘(C++)
Se-chan Oh
2022. 1. 7. 23:54
문제 링크 :
https://softeer.ai/practice/info.do?eventIdx=1&psProblemId=583&sw_prbl_sbms_sn=41516
문제 개요 :
소나기를 피해 몇 분만에 집에 도착하는지 구한다.
#include<iostream>
#include<vector>
#include<queue>
#include<tuple>
#define SPACE 100000
using namespace std;
int main(int argc, char** argv)
{
// 입력
int R,C;
cin >> R >> C;
queue<tuple<int,int,int>> rains; // 소나기 저장
queue<tuple<int,int,int>> car; // 차 위치 저장
int home[2]; // 집 위치 저장
vector<vector<int>> W_map(R,vector<int>(C,SPACE)); // 차 지나가는 곳 저장
vector<vector<int>> R_map(R,vector<int>(C,SPACE)); // 비 오는 곳 저장
for(int i=0;i<R;i++){
for(int j=0;j<C;j++){
char tmp;
cin >> tmp;
switch(tmp){
case'W': // 차 위치
car.push(make_tuple(i,j,0));
W_map[i][j]=0;
break;
case'H': // 집 위치
home[0]=i; home[1]=j;
R_map[i][j]=SPACE+1;
break;
case'*': // 소나기 위치
R_map[i][j]=0;
rains.push(make_tuple(i,j,0));
break;
case'X': // 강 위치
W_map[i][j]=-1;
R_map[i][j]=-1;
break;
}
}
}
int dir[4][2] = {{1,0},{0,1},{-1,0},{0,-1}}; // 움직일 방향
// R_map BFS
while(!rains.empty()){
int x = get<0>(rains.front());
int y = get<1>(rains.front());
int t = get<2>(rains.front());
rains.pop();
for(int i=0;i<4;i++){
int nx = x + dir[i][0];
int ny = y + dir[i][1];
if(nx<0 || nx>=R || ny<0 || ny>=C || R_map[nx][ny]!=SPACE) continue; // 비가 지나가지 못하는 곳은 패스
rains.push(make_tuple(nx,ny,t+1));
R_map[nx][ny] = t+1;
}
}
// W_map BFS
while(!car.empty()){
int x = get<0>(car.front());
int y = get<1>(car.front());
int t = get<2>(car.front());
car.pop();
for(int i=0;i<4;i++){
int nx = x + dir[i][0];
int ny = y + dir[i][1];
if(nx<0 || nx>=R || ny<0 || ny>=C || W_map[nx][ny]!=SPACE || t+1>=R_map[nx][ny]) continue; // 차가 지나가지 못하는 곳은 패스
car.push(make_tuple(nx,ny,t+1));
W_map[nx][ny] = t+1;
}
}
if(W_map[home[0]][home[1]]==SPACE) printf("FAIL"); // 차가 목적지에 도달하지 못함
else printf("%d",W_map[home[0]][home[1]]); // 차가 목적지에 도달함
return 0;
}
문제 해결 방법
1. 소나기 지도와 차 지도로 나누어 배열을 생성한다.
2. 소나기 지도 각 칸에 몇 분 뒤에 비가 오는지 기록한다. 이때 집과 강에는 비가 오지 않는다는 것을 고려해야 한다.
3. 차 지도 각 칸에 몇 분 뒤에 차가 도착하는지 기록한다. 이때 차는 강을 건널 수 없다는 것과 비가 오는 시간보다 늦게 도착하면 안된다는 것을 고려해야 한다.
4. 지도를 탐색할 때에는 BFS를 사용해야 한다.
5. 지도의 각 칸에 시간을 기록하는 시점이 중요한데, 큐에서 좌표를 꺼내고 시간을 저장하는 것이 아니라 큐에 좌표를 저장할 때 그 칸에 시간을 저장하는 것을 같이 처리해주어야 한다. 즉, 아래는 잘못된 코드이다.
// R_map BFS
while(!rains.empty()){
int x = get<0>(rains.front());
int y = get<1>(rains.front());
int t = get<2>(rains.front());
R_map[x][y] = t; // 이 시점에서 시간을 기록하면 안됨!!
rains.pop();
for(int i=0;i<4;i++){
int nx = x + dir[i][0];
int ny = y + dir[i][1];
if(nx<0 || nx>=R || ny<0 || ny>=C || R_map[nx][ny]!=SPACE) continue;
rains.push(make_tuple(nx,ny,t+1));
}
}
// W_map BFS
while(!car.empty()){
int x = get<0>(car.front());
int y = get<1>(car.front());
int t = get<2>(car.front());
W_map[x][y] = t; // 이 시점에서 시간을 기록하면 안됨!!
car.pop();
for(int i=0;i<4;i++){
int nx = x + dir[i][0];
int ny = y + dir[i][1];
if(nx<0 || nx>=R || ny<0 || ny>=C || W_map[nx][ny]!=SPACE || t+1>=R_map[nx][ny]) continue;
car.push(make_tuple(nx,ny,t+1));
}
}