题目是给你起点sx,和终点gx;牛在起点可以进行下面两个操作:
步行:John花一分钟由任意点X移动到点X-1或点X+1。
瞬移:John花一分钟由任意点X移动到点2*X。
你要输出最短步数及打印路径。
最短步数用bfs就行了。
至于路径,用一个结构体就可以去存每个点的父节点,再递归输出路径就行了。
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<queue>
using namespace std;
#define MAX 100010
int sx,gx,ans;
struct mask
{
mask(int x,int step):x(x),step(step){};
int x,step,f;
};/
struct node
{
int x;
}p[MAX];//保存父节点
queue<mask>q;
int dx[]={1,-1};
int flag=0;
bool vis[MAX];
bool check(int r)
{
return (0<=r&&r<=MAX);
}
void bfs()
{
flag=0;
while(!q.empty())q.pop();
q.push(mask(sx,0));
memset(vis,false,sizeof(vis));
vis[sx]=true;//printf("%d\n",q.front());
while(q.size())
{
mask tmp=q.front();q.pop();
// printf("ok\n");
if(tmp.x==gx)
{
ans=tmp.step;
flag=1;
break;
}
for(int i=0;i<2;i++)
{
int nx=tmp.x+dx[i];
if(check(nx)&&!vis[nx])
{
vis[nx]=true;
p[nx].x=tmp.x;
q.push(mask(nx,tmp.step+1));
}
}
int nx1=tmp.x*2;
if(check(nx1)&&!vis[nx1])
{
vis[nx1]=true;
p[nx1].x=tmp.x;
q.push(mask(nx1,tmp.step+1));
}
}
}
void pri(int x1)
{
if(x1==sx){
printf("%d ",sx);
return ;
}
pri(p[x1].x);
printf("%d ",x1);
}
int main()
{
while(~scanf("%d %d",&sx,&gx)){
if(sx==-1&&gx==-1)break;
bfs();
if(flag)
printf("%d\n",ans);
else printf("-1\n");
pri(gx);
printf("\n");
}
}