코딩테스트/C++
[ 백준 BOJ ] 2151번 - 거울 설치 (C++)
최-코드
2025. 6. 23. 20:55
https://www.acmicpc.net/problem/2151
생각 흐름
- 거울을 대각선으로만 설치할 수 있으므로 빛이 쏴졌을 때 이동할 경로는 상, 하, 좌, 우 밖에 없다. 즉, 빛이 쏘아진 방향에서 좌, 우로만 이동이 가능하다.
- 이 때 빛이 a,b 지점을 지났다고 했을 때 ➡️ 이렇게 쏴졌을 때랑 ⬆️ 이렇게 쏴졌을 때랑 빛이 이동하는 방향이 아예 달라지므로 방향을 따져가며 방문 체크를 해야 된다. 그렇게 [y][x][dir] 형태의 checked 배열을 만들었다.
- 결국 최단 경로 문제이기에 bfs 알고리즘을 사용해서 풀었다.
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
int N;
vector<string> input;
//cnt, directer(상0,하1,죄2,우3), y, x
queue<pair<pair<int,int>,pair<int,int>>> q;
//y, x, directer
bool checked[50][50][4];
int bfs(int y, int x, int dir){
q.push({{0,dir},{y,x}});
for(int i = 0; i<4; i++){
checked[y][x][i]=true;
}
while(!q.empty()){
int cnt = q.front().first.first;
int dir = q.front().first.second;
int y = q.front().second.first;
int x = q.front().second.second;
q.pop();
if(dir == 0){
int my = y;
while(true){
my--;
if(my<0) break;
if(input[my][x]=='*') break;
if(checked[my][x][0]) continue;
if(input[my][x]=='#') return cnt;
if(input[my][x]=='!'){
checked[my][x][0] = true;
q.push({{cnt+1, 2},{my, x}});
q.push({{cnt+1, 3},{my, x}});
}
}
}else if(dir == 1){
int my = y;
while(true){
my++;
if(my>N-1) break;
if(input[my][x]=='*') break;
if(checked[my][x][1]) continue;
if(input[my][x]=='#') return cnt;
if(input[my][x]=='!'){
checked[my][x][1] = true;
q.push({{cnt+1, 2},{my, x}});
q.push({{cnt+1, 3},{my, x}});
}
}
}else if(dir ==2){
int mx = x;
while(true){
mx++;
if(mx>N-1) break;
if(input[y][mx]=='*') break;
if(checked[y][mx][2]) continue;
if(input[y][mx]=='#') return cnt;
if(input[y][mx]=='!'){
checked[y][mx][2] = true;
q.push({{cnt+1, 0},{y, mx}});
q.push({{cnt+1, 1},{y, mx}});
}
}
}else{
int mx = x;
while(true){
mx--;
if(mx<0) break;
if(input[y][mx]=='*') break;
if(checked[y][mx][3]) continue;
if(input[y][mx]=='#') return cnt;
if(input[y][mx]=='!'){
checked[y][mx][3] = true;
q.push({{cnt+1, 0},{y, mx}});
q.push({{cnt+1, 1},{y, mx}});
}
}
}
}
return 987654321;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(NULL);
cin>>N;
int doorY=-1, doorX=-1;
for(int i = 0; i<N; i++){
string tmp;
cin>>tmp;
input.push_back(tmp);
for(int j = 0; j<N; j++){
if(tmp[j]=='#'){
doorY = i;
doorX = j;
}
}
}
int answer = 987654321;
for(int i = 0; i<4; i++){
answer = min(answer, bfs(doorY, doorX, i));
}
cout<<answer<<endl;
return 0;
}