【USACO】CODE[VS] 3060 && openjudge 2971 捉住那頭牛

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;
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章