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

来源:互联网 发布:游族网络(002174)股吧 编辑:程序博客网 时间:2024/05/01 17:34

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;} 
0 0
原创粉丝点击