3060 抓住那頭奶牛 USACO
時間限制: 1 s
空間限制: 16000 KB
題目等級 : 黃金 Gold
題解
題目描述 Description
農夫約翰被告知一頭逃跑奶牛的位置,想要立即抓住它,他開始在數軸的N 點(0≤N≤100000),奶牛在同一個數軸的K 點(0≤K≤100000)。約翰有兩種移動方式:1 分鐘內從x 點移動到x+1 或x-1;1 分鐘內從x 點移動到2x。假設奶牛不會移動,約翰抓住它需要多少時間?
輸入描述 Input Description
一行兩個整數N 和K,用空格隔開。
輸出描述 Output Description
約翰抓住它需要的最少時間。
樣例輸入 Sample Input
5 17
樣例輸出 Sample Output
4
思路:
BFS + 隊列
每到下一個的點 就把三種情況執行一次 更新狀態 將所有可能狀態入隊
因爲BFS按層遍歷的性質,第一次訪問到答案的時候一定是最優的
代碼:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
const int MAXN = 100005;
using namespace std;
queue<int> q;
int step[MAXN]; //跟隨數組,記錄步數
bool vis[MAXN];
int n,k,next,head;
int bfs()
{
q.push(n);
step[n]=0;
vis[n]=1;
while(!q.empty())
{
head=q.front();
q.pop();
//分三個方向BFS
for(int i=0; i<3 ;i++)//對其中一種情況一搜到底。。記錄所有路徑
{
if(i==0) next=head-1;
else if(i==1) next=head+1;
else next=head*2;
if(next > MAXN || next<0 ) continue; //必須先判斷,不然會RE,數組越界了
if(!vis[next])
{
q.push(next);
step[next]=step[head]+1;//前一條路徑數目,對應的走過的路程,即爲當前的路程數
vis[next]=1;
}
if(next==k) return step[next];//廣搜的特性,返回的第一個一定是最短的路徑
}
}
}
int main()
{
memset(vis,0,sizeof(vis));
scanf("%d%d",&n,&k);
if(n>=k)
{
printf("%d",n-k);
}
else
{
printf("%d",bfs());
}
return 0;
}