题目是给你起点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");
    }
}

05-26 07:25