ACM深度搜索整理1

来源:互联网 发布:淘宝身份认证失败 编辑:程序博客网 时间:2024/06/05 12:50

/*

Farmer John has been informed of the location of a fugitive cow and wants to catch her immediately. He starts at a point N (0 ≤ N ≤ 100,000) on a number line and the cow is at a point K (0 ≤ K ≤ 100,000) on the same number line. Farmer John has two modes of transportation: walking and teleporting.

* Walking: FJ can move from any point X to the points - 1 or + 1 in a single minute
* Teleporting: FJ can move from any point X to the point 2 × X in a single minute.

If the cow, unaware of its pursuit, does not move at all, how long does it take for Farmer John to retrieve it?

Input

Line 1: Two space-separated integers: N and K

Sample Input

5 17

Sample Output

4
本题大意,一个人一只牛,要求人以最小步数捉到牛,人有3种选择,当前位置*2,当前位置-1,当前位置+1,实际就是求最短路,所以用深度搜索,刚开始本人也有想到三种情况都入队,借助队列来解决。可是如何也没有一个清晰的思路,借助队友的思想,在加上自己的理解,终于对深度搜索有了新的搜获。以下是AC的代码,希望也能给你带来同样的收获。

*/

#include<iostream>
#include<queue>
using namespace std;
//定义数组,存放已经访问过的位置,默认为0
int visit[400000]={0};
//第一个代表横坐标既当前位置,第二个代表步数
typedef pair<int,int>p;
//初始化一个队列
queue<p>q;
//宽度优先搜索
//传入N和K
int bfs(int start,int end)
{
  //第一个位置
  p p1;
  p1.first=start;
  p1.second=0;
  //将起始位置入队
  q.push(p1);
  //标记访问过的位置,避免重复访问
  visit[p1.first]=1;
  //当队不为空时循环,每次取出队首元素
  while(q.size())
    {
     //出队首一个元素
     p1=q.front();
     //判断该元素的位置是否与牛的位置相同
     if(p1.first==end)
        {
        //如果相同,返回步数
        return p1.second;
        }
     //如果不同,步数加1
     p1.second++;
     //进入以下三种情况判断
     //注意这个p2相当一个中间介质
     p p2;
     //首先,当前位置小于牛的位置
     //对*2和+1两种情况进行入队
     if(p1.first<end)
        {
         //把步数增加后的p1赋给p2
         p2=p1;
         //当前位置*2后,获取新的位置赋给p2
         p2.first*=2;
         //判断该位置是否还没访问
         if(visit[p2.first]==0)
            {
             //将新位置p2入队
             q.push(p2);
             //标记该位置已经访问过
             visit[p2.first]=1;
            }
         //重新将p1赋给p2
         p2=p1;
         //当前位置加1后,获取新的位置赋给p2
         p2.first+=1;
         //判断该位置是否还没访问
         if(visit[p2.first]==0)
            {
             //将新位置p2入队
             q.push(p2);
             //标记该位置已经访问过
             visit[p2.first]=1;
            }
        }
     //当前的位置大于0
     //对-1这一种情况进行判断然后入队
     if(p1.first>0)
        {
         //重新将p1赋给p2
         p2=p1;
         //将前的位置-1后,获取新的位置赋p2
         p2.first-=1;
         //判断是否访问过
         if(visit[p2.first]==0)
            {
             //还没访问过就将其入队
             q.push(p2);
             //标记已经访问过了
             visit[p2.first]=1;
            }
        }
     //将队顶元素出队
     q.pop();
    }
}
int main()
{
    int ans=0;
    int N=0,K=0;
    cin>>N>>K;
    ans=bfs(N,K);
    cout<<ans<<endl;
return 0;
}

0 0