poj3278追逐母牛

题目描述:农夫约翰已被告知一头逃亡母牛的位置,并希望立即抓住她。他从数轴上的点N (0 ≤ N ≤ 100,000) 开始,而奶牛在同一数轴上的点K (0 ≤ K ≤ 100,000) 处。Farmer John 有两种交通方式:步行和传送。

1. 行走:FJ 可以在一分钟内从X点移动到X - 1 或X + 1点

2. 传送:FJ 可以在一分钟内从X点移动到 2 × X点。

假设母牛是不会动的,农夫约翰需要多长时间才能取回它?

输入:两个空格分隔的整数:NK

输出:农夫约翰抓住逃亡母牛所需的最少时间(min)

使用算法:广度优先搜索,农夫只有三种方式来捉到母牛,一是一步一步往前移,每移动一步需要1min,二是往后一步一步移动,三是移动到当前位置的两倍处。显然在离母牛远时用第三种方式更快,一旦不小心过了母牛,就只能采用方式二退回来,时间必然不是最少的,所以先分两种情况,一种是农夫在母牛前面,那么农夫就只能后退,时间就是农夫的位置减去母牛的位置,另外一种则要采用广度优先搜索算法得出最优解。

广度优先搜索的实现方法: 

1.设置一个队列Q,从队列的顶点开始,遍历该顶点后让其进队;

2.出队一个顶点元素,求该顶点的所有邻接点(对应于此题即FJ的三种走法)

3对于没有遍历过的邻接点遍历之,并 让其进队

 4.若队空停止,队不空时继续第2步。


代码部分:

#include<iostream>                    //导入相关头文件
#include<queue>
#include<cstring>
#include<cstdio>
using namespace std;
 
const int maxn=100001;
 
bool vis[maxn];                        //标记数组
int step[maxn];                       //记录到了到达每一个位置所走的步数
queue <int> q;                      //定义队列,实现广度优先搜索
 
int bfs(int n,int k)
{
    int head,next;                   //记录第一个位置和下一个位置
    q.push(n);                         //开始农夫在n位置,n入队
    step[n]=0;                        
    vis[n]=true;                        //用来标记是否已经访问
    while(!q.empty())              //当队列非空
    {
        head=q.front();               //取队首
        q.pop();                         //弹出对首
        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<0 || next>=maxn) continue;           //排除出界情况
            if(!vis[next])                                                //如果next位置未被访问
            {
                q.push(next);                                          //入队
                step[next]=step[head]+1;                       //步数加1
                vis[next]=true;                                        //标记设为被访问
            }
            if(next==k) return step[next];                     //当遍历到母牛位置,返回步数
        }
    }
}
int main()                                                               #主函数部分
{
    int n,k;
    while(cin>>n>>k)
    {
        memset(step,0,sizeof(step));                          //数组和变量的初始化,防止乱码的出现
        memset(vis,false,sizeof(vis));
        
        while(!q.empty()) q.pop();                              //注意调用前要先清空,没有清空会无法ac
        if(n>=k) printf("%d\n",n-k);
        else printf("%d\n",bfs(n,k));
    }
    return 0;

}

 这是一道广度优先搜索的入门题目,可以帮助我们更好的了解广度优先搜索和队列的使用方法,提交可以ac。

猜你喜欢

转载自blog.csdn.net/zjsru_Beginner/article/details/121067623
今日推荐