- 本题采用BFS三个方向进行搜索,根据BFS或者spfa算法可知每次选择距离减小的点去更新其他的点,当第一次到达终点时即为最短路径。
- 当有一个大于终点的状态出现时,可以按照BFS依次减一标记它到终点的所有点,也可以直接输出通过这条路径到到终点的距离,不标记。
- stl的queue要一百多ms,估计可能内存扩展太多,影响时间。利用自写的队列,开到适量大小(35000)可以达到0ms。
#include<cstdio>
#define maxN 200005
#define qSize 35000
struct node
{
int num;
int step;
};
char vis[maxN];
node q[qSize+1];
int minStep;
int destNum;
int qHead,qTail;
int enQueue(node x)
{
q[qTail] = x;
if(qTail == qSize)
qTail = 0;
else
qTail++;
return 0;
}
node deQueue()
{
node x = q[qHead];
if(qHead == qSize)
qHead = 0;
else
qHead++;
return x;
}
bool judge(node next)
{
if(next.num == destNum)
{
if(minStep > next.step)
minStep = next.step;
return 1;
}
vis[next.num] = true;
enQueue(next);
return 0;
}
int main()
{
node now,next;
while(~scanf("%d%d",&now.num,&destNum))
{
if(now.num >= destNum)
{
printf("%d\n",now.num-destNum);
return 0;
}
now.step = 0;
enQueue(now);
minStep = maxN;
vis[now.num] = true;
while(qHead != qTail)
{
now = deQueue();
next.step = now.step+1;
if(now.num > destNum) //大于目的点只能减到终点,所以可以不用再搜索
{
if(minStep > now.step+now.num-destNum)
minStep = now.step+now.num-destNum;
}
else
{
if((next.num = now.num-1) >= 0&&!vis[next.num]&&judge(next)) //减一
break;
if(!vis[next.num = now.num<<1]&&judge(next)) //乘以2
break;
if(!vis[next.num = now.num+1]&&judge(next)) //加一
break;
}
}
printf("%d\n",minStep);
}
return 0;
}