NOI 4.7 搜索 6043:哆啦A梦的时光机

题目来源:http://noi.openjudge.cn/ch0407/6043/

6043:哆啦A梦的时光机

总时间限制1000ms   内存限制65536kB

描述

哆啦A梦有一个神奇的道具:时光机。坐着它,大雄和他的伙伴们能穿越时空,回到过去或者去到未来。

有一天,大雄和他的伙伴们想穿越时空进行探险,可是时光机却出了一点故障,只能进行有限的时空穿越操作。大雄他们需要从现在出发,到达一个目标时间点进行探险,结束后再返回到现在,他们希望尽可能减少时光机的操作次数,你能帮助他们吗?

假设大雄和他的伙伴们出发的时间点(现在)为S0 < S < 1,000,000),希望到达的时间点(目标)为T0 < 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行,每一行包含两个正整数ST,表示出发和到达时间点。S≠T

输出

输出包括N行,每一行一个正整数,表示每组测试数据对应的最少时光机操作次数。

样例输入

2
5 17
4 8

样例输出

8
2

提示

对于S=5T=17
操作如下:5->4->8->16->17->16->8->4->5
对于S=4T=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
}


猜你喜欢

转载自blog.csdn.net/da_kao_la/article/details/80861444
4.7