https://vjudge.net/contest/425322#problem/B
题目大意
从数轴上A点出发(坐标n)到达K点(坐标k)。有两种移动方法:
1.左右横跳 向左一格或者向右一格
2.跳到目前坐标两倍的地方
问最少需要多少步。
思路与细节
这个题用bfs,因为到达的每一个点都是一个状态。不太适合dfs,很难划定什么时候dfs该停下来,而且问的是最少用多少步,所以必须是bfs。
但是要注意bfs的边界条件。
首先,坐标要一直>=0。其次,由于限定了n,k的上界,所以当bfs后超过上界以后,可以舍掉。
当然,如果n>=k,就用不着bfs了,答案必须是n-k。
代码
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <queue>
using namespace std;
int n,k,flag=0;
const int maxn=2e5+5;
int vis[maxn];///要及时记录已经到过的点哦
struct node
{
int x;int step;
};
int bfs(int pos)
{
queue<node>q;
node head;
head.step=0,head.x=pos;
q.push(head);
while(!q.empty())
{
head=q.front();
q.pop();
if(head.x==k) return head.step;
int m=0;
for(int i=1;i<=3;i++)
{
switch(i)///语法处理
{
case 1:m=head.x+1;break;
case 2:m=head.x-1;break;
case 3:m=head.x*2;break;
}
if(m>=1&&m<200000&&!vis[m])///边界条件
{
vis[m]=1;
node next;
next.step=head.step+1,next.x=m;
q.push(next);
}
}
}
return -1;
}
int main()
{
scanf("%d%d",&n,&k);
memset(vis,0,sizeof(vis));
if(n>=k)
{
printf("%d\n",n-k);
return 0;
}
printf("%d\n",bfs(n));
return 0;
}