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