第一次竞赛-D.量子能力猫

一只掌握量子力学的猫试图从第X号箱子到达第Y号箱子,每次可以走相邻箱子或量子转移。通过广度优先搜索算法,可以找到猫到达目标所需的最小转移次数。当Y小于X时,猫需逐个箱子前进;否则,使用BFS遍历解空间,记录已访问状态,直至找到目标位置。

猫从薛定谔的箱子里成功存活并逃脱出来,这时它发现它已经掌握了量子力学的原理并拥有运用量子的能力。即便这样它还是克服不了它喜欢钻入纸箱的天性。
假设现在有一排纸箱的一端从0开始依次编号,这只猫可以以如下的方式在箱子之间行动:

  • 走到相邻箱子:从第X号箱子走到相邻的第X+1号或X-1号箱子。
  • 量子形式转移:从第X号箱子以量子态形式转移到2X号箱子里。

不论是用走的方法还是量子转移的方法,都算作一次转移。假设现在这只猫在第X号箱子里,它希望到第Y号箱子中,请问最少需要几次转移可以达到.

 

输入数据

输入只有一行,两个整数X Y由一个空格隔开

X Y

0≤X,Y≤100000

输出数据

输出一行,一个整数,表示猫进行转移的最小次数

样例

输入

5 17

输出

4

提示

最快的方式是5-10-9-18-17,这样猫转移了4次

题解:一般找最短方案都是用广度优先搜索,不只是图算法里有广度优先算法,对解空间进行遍历也可以使用BFS进行搜索。
简单情形,猫初始在X号箱子,它想去的Y号箱子比X的号码小,这时它只能逐个箱子的走过去,这时直接输出X-Y.
其它情形,就进行广度优先搜索,第k次移动处于位置x的时候,第k+1次移动可能处于x+1,x-1或2x,为节省时间,要保证x+1,x-1和2x以前没走过,这儿加个数组判断这个点x+1,x-1,2x以前是否没走到,若没走到的话就走过去。可以设定一个结构体记下当前的移动次数level和坐标data,初始data=X,level=0放入队列,从队列出取一个数,检查x+1,x-1,2x是否没有被访问过,没访问过的就以level=level+1和相应data入队,直到发现data=Y的时候,输出移动步数level并终止程序. 

#include <cstdio>
#include <queue>
#define MAXN 100003
using namespace std;

struct qNode
{
    int data;//坐标
    int level;//移动次数
};

int main(void)
{
    bool visited[MAXN]={0};
    queue<qNode> q;
    qNode *p,*n1,*n2,*n3;
    int start,target;
    scanf("%d%d",&start,&target);
    if(start>=target)//在当前位置后面
    {
        printf("%d\n",start-target);
    }
    else
    {
        p=new qNode;
        n1=new qNode;//前进一步
        n2=new qNode;//后退一步
        n3=new qNode;//走2倍步
        p->data=start;
        p->level=0;
        visited[start]=true;
        q.push(*p);//将走过的点加入队列中
        while(q.size()>0)
        {
            *p=q.front();
            q.pop();

            if(p->data==target)
            {
                printf("%d\n",p->level);
                break;
            }
            if( p->data+1<MAXN && visited[p->data+1]==false)
            {
                n1->data=p->data+1;
                visited[p->data+1]=true;
                n1->level=p->level+1;
                q.push(*n1);
            }
            if( p->data-1>=0 && visited[p->data-1]==false)
            {
                n2->data=p->data-1;
                visited[p->data-1]=true;
                n2->level=p->level+1;
                q.push(*n2);
            }
            if(p->data*2<MAXN && visited[p->data*2]==false)
            {
                n3->data=p->data*2;
                visited[p->data*2]=true;
                n3->level=p->level+1;
                q.push(*n3);
            }
        }
    }
    return 0;
}

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值