【OJ】抓牛问题

/*
农夫John的奶牛跑路了。将地图视作一条数轴,John的初始位置在s而奶牛的位置在t(0<=s,t<=100000)。John可以花费一分钟的时间使自己作如下移动:

1 从点x移动到点x+1
2 从点x移动到点x-1
3 从点x移动到点x*2
奶牛的位置一直在点t。现在给定s,t,要求John要追上奶牛最少需要几分钟。

Sample Input:
5 17

Sample Output:
4

Description:
5->4->8->16->17
*/

#include<iostream>
#include<queue>
#include<cmath>
#include<cstdlib>
#include<cstdio>
#include<cstring>
using namespace std;
const int M=100010;

int bfs(int s,int t)
{
    queue<int> q;
    int head,next;
    int vis[M],step[M];
    memset(vis,0,sizeof(vis));
    memset(step,0,sizeof(step));
    q.push(s);
    step[s]=0;
    
    while(!q.empty())
    {
        head=q.front();
        q.pop();
        for(int i=0;i<3;i++)
        {
            if(i==0)
                next=head-1;
            if(i==1)
                next=head+1;
            if(i==2)
                next=head*2;
            if(next<0||next>M)
                continue;
            if(vis[next]==0)
            {
                vis[next]++;
                step[next]=step[head]+1;
                q.push(next);
            }
            if(next==t)
                return step[next];
        }
    }
}


int main()
{
    int s,t;
    while(scanf("%d %d",&s,&t)==2&&s>=0&&t<=M)
    {
        if(t<=s)//牛在人后面 
            cout<<abs(s-t)<<endl;
        else 
            cout<<bfs(s,t)<<endl;
    }
    
    return 0;
}


/*
#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);   //开始FJ在n位置,n入队
    step[n]=0;
    vis[n]=true; //标记已访问
    while(!q.empty())  //当队列非空
    {
        head=q.front();  //取队首
        q.pop();         //弹出对首
        for(int i=0;i<3;i++)     //FJ的三种走法
        {
            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(); //注意调用前要先清空
        if(n>=k) printf("%d\n",n-k);
        else printf("%d\n",bfs(n,k));
    }
    return 0;
}
*/

/*
#include<iostream>
#include<queue>
#include<cstring>
#include<cstdio>
#include <algorithm>
using namespace std;
 
queue<int> q;
int  m,n;
int step[100010];
int vis[100010];
int rear,front;//rear表示下一步 
int BFS(){
    int i;
    q.push(n);//把农民的位置压入队列 
    step[n]=0;//步数记为0 
    vis[n]=1;////标记这个点走过 
    while(!q.empty()){//队列不为空哦时执行 
        front=q.front();//最开始的位置 
        q.pop();//弹出队列头 
        for(i=0;i<3;i++)//三种走法,三种循环 
        {
            if(i==0)
            rear=front+1;//第一种下一步+1 
            if(i==1)
            rear=front-1;//第二种下一步-1 
            if(i==2)
            rear=front*2;//第三种步数翻倍 
            if(rear>=0&&rear<=100000&&vis[rear]==0)//判断是否越界,并且这一步没有走过 
            {
                vis[rear]=1;//标记这一步走过了 
                step[rear]=step[front]+1;// 步数+1 
                q.push(rear);//将当前位置压入队列 
            }
            if(rear==m)return step[rear];
        }
    }return -1;
    
}
 
int main()
{
    
    cin>>n>>m;
        memset(step,0,sizeof(step));//初始化为0 
        memset(vis,0,sizeof(vis));//初始化为false
        cout<<BFS();
    
    return 0;
}
*/

 

 

tz@HZAU

2019/3/4

posted on 2019-03-04 10:40  tuzhuo  阅读(438)  评论(0编辑  收藏  举报