문제
"맞았습니다" 코드
#include <bits/stdc++.h>
#define X first
#define Y second
using namespace std;
int n, k;
int vis[100005];
bool rangecheck(int x){
return (x >=0 && x <= 100000);
}
void bfs(){
queue<int> qu;
vis[n] = 0; // 수빈이의 현재 위치는 0초에 도달.
qu.push(n);
while(!qu.empty()){
int cx = qu.front();
qu.pop();
if(cx == k){
cout << vis[cx]<< '\n';
break;
}
for(auto nx : {cx*2, cx + 1, cx - 1}){
if(!rangecheck(nx) || vis[nx] <= (vis[cx]+1)) continue;
if((cx*2) == nx) {
vis[nx] = vis[cx];
}else{
vis[nx] = vis[cx] + 1;
}
qu.push(nx);
}
}
}
int main(void) {
ios::sync_with_stdio(0);
cin.tie(0);
int bignum = 1e9;
fill(vis, vis+100004, bignum);
cin >> n >> k;
bfs();
return 0;
}
리뷰
다시 풀어봐야 할 문제.
내가 위치 2에 있다.
위치 2에서 '위치 4'로 이동할 때, 예전에 방문할 때 보다 '적은 시간'이 걸려야 한다.
즉, '위치 4'로 가는 시간이 2초가 걸릴 수도 있고, 0초가 걸릴 수도 있다.
현재 위치2 이고, 이동 방법은 x2 해서 순간이동 하는방법, +1또는 -1하는데 1초가 걸리는 방법이 있다.
+1 을 2번 하면 2초가 걸려서 위치 4에 도착할 수 있다.
x2를 하고 순간이동하면 0초가 걸려서 위치 4에 도착할 수 있다.
따라서 위치 배열 인덱스 4에는 '0초'가 저장되어야 한다.
'가장 빠른 시간' 을 구해야 하니까 모든 위치의 초기 시간값을 2^9 로 크게 잡아놨다.
bfs로 순회할 때, "예전에 방문할 때 보다 '적은 시간'이 걸려야 한다" 를 만족시키기 위한 조건이 필요했다.
그래서 '현재시간 +1초' 와 다음위치가 저장하고 있는 도달 시간을 비교했다. 다음위치가 저장하고 있는 도달 시간이 더 커야 이동할 수 있게 했다.
현재 위치 시간이 2초 라고 했을 때. 2초 + 1초, 즉 3초가 다음 위치에 저장할 시간이 된다.
현재까지는 2초가 걸렸고 다음 위치에는 3초가 걸릴 수 있는 방법으로 현재까지 도달해왔다는 뜻이다.
다음 위치에 이미 3초가 저장되어 있다면, 다음 위치의 시간을 더 짧게 갱신해줄 필요가 없다.
다음 위치에 만약 4초가 저장되어 있다면, 3초를 저장하려고 했으니까 갱신해주면 된다.
728x90
'알고리즘 > 백준' 카테고리의 다른 글
나무 자르기 백준 2805 c++ (0) | 2021.12.06 |
---|---|
토마토 백준 7569 c++ (0) | 2021.12.06 |
적록색약 백준 10026 c++ (0) | 2021.12.03 |
유기농 배추 백준 1012 c++ (0) | 2021.12.03 |
나이트의 이동 백준 7562 c++ (0) | 2021.12.03 |