题目来源:http://noi.openjudge.cn/ch0407/6043/
6043:哆啦A梦的时光机
总时间限制: 1000ms 内存限制: 65536kB
描述
哆啦A梦有一个神奇的道具:时光机。坐着它,大雄和他的伙伴们能穿越时空,回到过去或者去到未来。
有一天,大雄和他的伙伴们想穿越时空进行探险,可是时光机却出了一点故障,只能进行有限的时空穿越操作。大雄他们需要从现在出发,到达一个目标时间点进行探险,结束后再返回到现在,他们希望尽可能减少时光机的操作次数,你能帮助他们吗?
假设大雄和他的伙伴们出发的时间点(现在)为S(0 < S < 1,000,000),希望到达的时间点(目标)为T(0 < T <1,000,000),已知时光机可以进行如下的时空穿越操作(X为正整数):
1. 可以从任意时刻X穿越到X+1或者X-1时刻
2. 可以从任意时刻X穿越到X*2时刻
3. 当X为偶数时,可以从X时刻穿越到X/2时刻
请问,大雄和他的伙伴们从S时刻出发,先到达T时刻,再回到S时刻最少需要多少次时空穿越操作?
输入
输入的第一个数是一个正整数N,表示测试数据一共有N组(0 < N < 20)。
之后有N行,每一行包含两个正整数S和T,表示出发和到达时间点。S≠T
输出
输出包括N行,每一行一个正整数,表示每组测试数据对应的最少时光机操作次数。
样例输入
2
5 17
4 8
样例输出
8
2
提示
对于S=5,T=17:
操作如下:5->4->8->16->17->16->8->4->5
对于S=4,T=8:
操作如下:4->8->4
-----------------------------------------------------
思路
广搜最短路。
-----------------------------------------------------
代码
#include<fstream>
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
const int NMAX = 3000000;
bool mat[NMAX] = {}; // 该数字是否被访问过
struct node {
int num,cnt;
node (int nn, int cc): num(nn), cnt(cc) {}
};
int bfs(int s, int t)
{
if (s==t)
{
return 0;
}
memset(mat,0,sizeof(mat));
mat[s] = 1;
node nd(s,0);
int mynum;
queue<node> qn;
qn.push(nd);
while (!qn.empty())
{
nd = qn.front();
mynum = nd.num;
qn.pop();
if (mynum+1<NMAX && !mat[mynum+1])
{
if (mynum+1==t)
{
return nd.cnt+1;
}
node nd1(mynum+1, nd.cnt+1);
qn.push(nd1);
mat[mynum+1] = 1;
}
if (mynum>1 && !mat[mynum-1])
{
if (mynum-1==t)
{
return nd.cnt+1;
}
node nd1(mynum-1, nd.cnt+1);
qn.push(nd1);
mat[mynum-1] = 1;
}
if (mynum*2 < NMAX && !mat[mynum*2])
{
if (mynum*2==t)
{
return nd.cnt+1;
}
node nd1(mynum*2, nd.cnt+1);
qn.push(nd1);
mat[mynum*2] = 1;
}
if (mynum%2==0 && mynum>=2 && !mat[mynum/2])
{
if (mynum/2==t)
{
return nd.cnt+1;
}
node nd1(mynum/2, nd.cnt+1);
qn.push(nd1);
mat[mynum/2] = 1;
}
}
return -1;
}
int main()
{
#ifndef ONLINE_JUDGE
ifstream fin ("0407_6043.txt");
int n,s,t;
fin >> n;
while (n--)
{
fin >> s >> t;
cout << 2*bfs(s,t) << endl;
}
fin.close();
#endif
#ifdef ONLINE_JUDGE
int n,s,t;
cin >> n;
while (n--)
{
cin >> s >> t;
cout << 2*bfs(s,t) << endl;
}
#endif
}