John在位置N處,奶牛在K處,John每次只能有以下兩種移動方式:walking和teleporting
Walking:在一個單位時間裏John可以從X處移動到X-1或X+1。
Teleporting:在一個單位時間裏John可以從X處移動至2*X。
假設奶牛的位置不變,求John移動到奶牛所在位置所需的最短時間。
主要方法:用隊列進行寬度優先搜索BFS,同時用一個數組標記已經訪問過的點,減少算法時間。注意要考慮N >= K的情況,此時,N只能一直減一,直至等於K。
#include <iostream>
#include <vector>
#include <queue>
#include <stdio.h>
using namespace std;
int main(){
int n, k;
cin >> n >> k;
int ans = 0;
if(k <= n){
while(k != n){
n--;
ans++;
}
cout << ans << endl;
return 0;
}
queue<int> que;
que.push(n);
vector<int> arr(2*k+1, -1);
arr[n] = 0;
while(!que.empty()){
int s = que.size();
bool stop = false;
while(s--){
int num = que.front();
que.pop();
if(num == k) {
stop = true;
break;
}
if(num+1 <= 2*k && arr[num+1] == -1){
que.push(num+1);
arr[num+1] = ans;
}
if(num-1 >= 0 && num-1 <= 2*k && arr[num-1] == -1){
que.push(num-1);
arr[num-1] = ans;
}
if(2*num <= 2*k && arr[2*num] == -1){
que.push(2*num);
arr[2*num] = ans;
}
}
if(stop) break;
ans++;
}
printf("%d\n", ans);
return 0;
}