【简单搜索】 POJ 3278 Catch That Cow 详解

Catch That Cow:

题目链接:https://vjudge.net/problem/POJ-3278

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

Output:

Line 1: The least amount of time, in minutes, it takes for Farmer John to catch the fugitive cow.

 分析:

  Farmer John要在一条数轴上用最快的速度走到一个定点

  他每次都有三种走法:

  ①前移一格

  ②后移一格

  ③前移x格(x为当前的位置)

  可以抽象为向三个方向搜索的广搜

   (因为是最优解问题所以用广搜)

  时间复杂度分析:

  在不剪枝的情况下, 每次有三个方向

  那么走一步有3种可能;

  走两步就是3*3种可能;

  走三步就是3*3*3种可能;

  那么也就是3^n次搜索(n为找到答案所需的最少步数)

  而这道题考虑较坏的情况,从1走到100000;

  最快的走法是每次×2,那么也需要将近17次吧(2^17=131072)

  如果不剪枝,搜索次数将达到恐怖的3^17,肯定tle;

  如何剪枝:

  ①首先想到如果farmer 在数轴上靠后的位置,而cow在数轴上靠前的位置

  比如farmer在100,cow在2;

  那么显然因为farmer只有一种走法能往回走(也就是x-1),这种情况可以直接算出答案(否则你得走98步,时间复杂度必然爆炸)

  ②其次,想到了用vis数组记忆走过的点

   因为广搜是一层层往外搜的,如果你当前搜到的点是已经被搜过了,那么你这条路必然不是最快的路。

   AC代码:

int N,K;
int vis[100005];

int bfs(){
    int ret=0;
    queue<int>q;
    q.push(N);
    while(!q.empty()){
        int t=q.size();
        while(t--){
            int temp=q.front();q.pop();
            if(temp==K) return ret;
            if(2*temp<=100000&&!vis[2*temp]) {vis[2*temp]=1;q.push(2*temp);}
            if(temp+1<=100000&&!vis[temp+1]) {vis[temp+1]=1;q.push(temp+1);}
            if(temp-1>=0&&!vis[temp-1]) {vis[temp-1]=1;q.push(temp-1);}
        }
        ret++;
    }
}

int main(){
    scanf("%d%d",&N,&K);
    if(N>=K) printf("%d",N-K);
    else printf("%d",bfs());
}

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值