[kuangbin带你飞]专题一 简单搜索 Catch That Cow : bfs

题意:

有两个数n和k,有三种操作:+1 、-1、*2,问从数字n到k 最少需要多少步!

由于是求最少步,所有用bfs来搜索。


题解:

这是道简单题,但是容易出现小问题,导致不容易AC。

首先,通过标记数组vis[i ],可以确保每个数只访问一次,同时vis[i]可以用来记录步数。

经过一次变换后的数字 nxt,范围是[0 , MaxN];

这里的数据范围是0-100000;


第一次AC的代码:32ms,写得太丑了

#include<cstdio>
#include<cstring>
#include <iostream>
#include<algorithm>
#include<queue>
using namespace std;

typedef struct Node{
    int indx,dis;
}Node;



int f[300005];
int ok;

int main(int argc, const char * argv[]) {
    
    int n,k,ans;
    
    while(~scanf("%d%d",&n,&k)){
    
        if(n>=k) {printf("%d\n",n-k);continue;}
        
        memset(f,-1,sizeof(f));
        queue<int >Q;
        f[n]=0;
        
        ok=0;
        ans=-1;
        
        Q.push(n);
        while(!Q.empty() && !ok){
        
            int cur,nxt,stp; // stp代表nxt的当前步数
            cur=Q.front();
            stp=f[cur]+1;
            
            if(cur==k) {ans=f[cur]; ok=1; break; }
            //+
            nxt=cur+1;
            if(nxt<k*2) //不能无限加
                if((f[nxt]>=0 && stp<f[nxt]) || f[nxt]<0) //如果当前位置有历史决策,新决策比历史决策要好
                {
                    f[nxt]=stp;
                    Q.push(nxt);
                }
            
            //-
            nxt=cur-1;
            if(nxt>=n/2) //不能无限减
                if((f[nxt]>=0 && stp<f[nxt]) || f[nxt]<0) //如果当前位置有历史决策,新决策比历史决策要好
                {
                    f[nxt]=stp;
                    Q.push(nxt);
                }
            
            //*2
            nxt=cur*2;
            if(nxt<k*2) //不能无限乘
                if((f[nxt]>=0 && stp<f[nxt]) || f[nxt]<0) //如果当前位置有历史决策,新决策比历史决策要好
                {
                    f[nxt]=stp;
                    Q.push(nxt);
                }
            
            Q.pop();
        }
        
        //if(ok)
            printf("%d\n",ans);
        //else while(1);
        
        
    }
    
    
    return 0;
}


第二次AC的代码: 0ms

#include<cstdio>
#include<cstring>
#include <iostream>
#include<algorithm>
#include<queue>
using namespace std;

int vis[100005];

int bfs(int n,int k){
    int ret=-1;
    
    memset(vis,-1,sizeof(vis));
    vis[n]=0;
    queue<int >Q;
    Q.push(n);
    
    while(!Q.empty()){
    
        int cur,nxt;
        cur=Q.front();
        if(cur==k) {ret=vis[cur];break;}
        
        for(int i=0;i<3;i++){
            
            if(i==0) nxt=cur+1;
            if(i==1) nxt=cur-1;
            if(i==2) nxt=cur*2;
        
            if(nxt<0 || nxt>100005 || vis[nxt]>=0) continue;
            
            vis[nxt]=vis[cur]+1;
            Q.push(nxt);
        }
        Q.pop();
    
    }
    
    return ret;
}


int main(){

    int n,k;
    
    while(~scanf("%d%d",&n,&k)){
    
        if(n>=k) {
            printf("%d\n",n-k);
            continue;
        }
    
        printf("%d\n",bfs(n,k));
    
    }


    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值