题意:在一直线段上给出起点和终点,每次移动可以向右或向左移动一个单位长度,或者直接使该点坐标乘以二,求从起点到终点的最短步数。
一维的广搜,一开始默认最短路径是两点间的直线距离, 搜索时只要路径长度大于该默认最短路径,就不继续搜索(不这么做容易RE,本弱一开始就RE了两发,智商不足啊。。。)
#include <cmath>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <stack>
#include <queue>
#include <cstring>
#include <ctype.h>
#define MAXN 2000100
using namespace std;
int n, k;
bool vis[MAXN];
int cnt[MAXN];
#define INF 2100000000
bool isleagal(int m)
{
if(m < 0 || m-k > abs(k-n) || vis[m] == 1 ) return 0;
return 1;
}
int main()
{
//freopen("C:/Users/zts/Desktop/in.txt", "r", stdin);
while(cin >> n >> k)
{
memset(vis, 0, sizeof(vis));
memset(cnt, 0, sizeof(cnt));
int ans = abs(k-n);
queue<int> q;
q.push(n);
vis[n] = 1;
while(!q.empty())
{
int src = q.front();
q.pop();
if(src == k)
{
ans = cnt[src];
break;
}
int x = src + 1;
int y = src - 1;
int z = src*2;
if(isleagal(x))
{
q.push(x);
vis[x] = 1;
cnt[x] = cnt[src]+1;
}
if(isleagal(y))
{
q.push(y);
vis[y] = 1;
cnt[y] = cnt[src]+1;
}
if(isleagal(z))
{
q.push(z);
vis[z] = 1;
cnt[z] = cnt[src]+1;
}
}
cout << ans << endl;
}
return 0;
}