1. 程式人生 > >Openjudge 2971:抓住那頭牛&&P1588 丟失的牛

Openjudge 2971:抓住那頭牛&&P1588 丟失的牛

ams problem radi 計算 span 位置 深度 mic while

蒟蒻的第一次發題解

經過了深思熟慮

選中了一道經典BFS(隊列)題

2971:抓住那頭牛

總時間限制:
2000ms
內存限制:
65536kB
描述

農夫知道一頭牛的位置,想要抓住它。農夫和牛都位於數軸上,農夫起始位於點N(0<=N<=100000),牛位於點K(0<=K<=100000)。農夫有兩種移動方式:

1、從X移動到X-1或X+1,每次移動花費一分鐘 2、從X移動到2*X,每次移動花費一分鐘 假設牛沒有意識到農夫的行動,站在原地不動。農夫最少要花多少時間才能抓住牛?

輸入
兩個整數,N和K
輸出
一個整數,農夫抓到牛所要花費的最小分鐘數
樣例輸入
5 17
樣例輸出
4

看到這道題首先想到的是搜索算法

本蒟蒻個人認為這道題BFS可以solve problem easily

大致思想如下:

用一個長的隊列來記錄能到達的距離

令相同時間走到的距離在同一深度

代碼中,第i個數的深度即dep[i]

所以第一個值為k的數的深度就是答案

不多說了

上代碼

#include<iostream>//樸素的頭文件 
using namespace std;
int n,k,que[100005],dep[100005],head,tail; //標準的變量名 不用解釋吧
bool a[100005];//確保步數最少 
int main()
{
    cin>>n>>k;
    if(n>=k)
    {
        cout
<<n-k; //後退只能一步一步走 return 0; } a[n]=true;head=1,tail=1; dep[1]=0;que[1]=n; while(head<=tail) { if(que[head]+1==k||que[head]-1==k||que[head]*2==k) //接下來的操作會使隊列多三個元素,所以要事先判斷 { cout<<dep[head]+1; return 0;//完美結束!!! }
if(!a[que[head]+1]&&que[head]+1<100005)//走法1 { tail++; que[tail]=que[head]+1; dep[tail]=dep[head]+1; a[que[tail]]=true; } if(!a[que[head]-1]&&que[head]-1>=0)//走法2 { tail++; que[tail]=que[head]-1; dep[tail]=dep[head]+1; a[que[tail]]=true; } if(!a[que[head]*2]&&que[head]*2<100005)//走法3 { tail++; que[tail]=que[head]*2; dep[tail]=dep[head]+1; a[que[tail]]=true; } head++;//移動頭指針 } return 0; }


題目分割線~~~

關於這只牛

我大洛谷上也有一道相似的黃題

P1588 丟失的牛

題目描述

FJ丟失了他的一頭牛,他決定追回他的牛。已知FJ和牛在一條直線上,初始位置分別為x和y,假定牛在原地不動。

FJ的行走方式很特別:他每一次可以前進一步、後退一步或者直接走到2*x的位置。計算他至少需要幾步追上他的牛。

輸入輸出格式

輸入格式:

第一行為一個整數t(≤10),表示數據組數;接下來每行包含一個兩個正整數x和y(0<x,y≤10^5),分別表示FJ和牛的坐標。

輸出格式:

對於每組數據,輸出最少步數。

輸入輸出樣例

輸入樣例#1: 復制
1 
5 17
輸出樣例#1: 復制
4

這道題只需把以上代碼寫到函數裏就好

代碼如下

#include<iostream>
#include<cstring>//本人不喜用萬能頭文件 
using namespace std;
int n,k,que[200005],dep[200005],head,tail;
bool a[200005]; //洛谷的數據比較苛刻,數組範圍需要改一改 
void bfs()
{ 
    if(n>=k)
    {
        cout<<n-k<<endl; //後退只能一步一步走 
        return;
    }
    a[n]=true;head=1,tail=1;
    dep[1]=0;que[1]=n;
    while(head<=tail)
    {
        if(que[head]+1==k||que[head]-1==k||que[head]*2==k)
        //接下來的操作會使隊列多三個元素,所以要事先判斷 
        {
            cout<<dep[head]+1<<endl; 
            return; 
        }
        if(!a[que[head]+1]&&que[head]+1<100005)//走法1 
        {
            tail++;
            que[tail]=que[head]+1;
            dep[tail]=dep[head]+1;
            a[que[tail]]=true; 
        }
        if(!a[que[head]-1]&&que[head]-1>=0)//走法2 
        {
            tail++;
            que[tail]=que[head]-1;
            dep[tail]=dep[head]+1;
            a[que[tail]]=true;     
        }
        if(!a[que[head]*2]&&que[head]*2<100005)//走法3 
        {
            tail++;
            que[tail]=que[head]*2;
            dep[tail]=dep[head]+1;
            a[que[tail]]=true; 
        }
        head++;//移動頭指針 
    } 
}
int main()
{
    int s,i;
    cin>>s;
    for(i=1;i<=s;i++)
    {
        cin>>n>>k;
        memset(que,0,sizeof(que));
        memset(dep,0,sizeof(dep));
        memset(a,0,sizeof(a));
        bfs();
    }
    return 0;
}

好了,本題解完美結束

Openjudge 2971:抓住那頭牛&&P1588 丟失的牛