C++广度优先搜索算法之哆啦A梦的时光机

版权声明:本文为博主原创文章,转载时请标明原创地址。 https://blog.csdn.net/C20190413/article/details/73380821


哆啦A梦的时光机

Description

哆啦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时刻最少需要多少次时空穿越操作?

Input

输入的第一个数是一个正整数N,表示测试数据一共有N组(0 < N < 20)。
之后有N行,每一行包含两个正整数S和T,表示出发和到达时间点。S≠T

Output

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

Sample Input

2
5 17
4 8

Sample Output

8
2

Hint

对于S=5,T=17:
操作如下:5->4->8->16->17->16->8->4->5
对于S=4,T=8:
操作如下:4->8->4

代码

其实这道题和抓住那头牛差不多。
代码在手,万事无忧(前方高能):
#include<cstdio>
#include<cstring>
const int sb=1e6;
bool mark[sb+1];
int que[sb+1],pre[sb+1],n,k;
int next;
void print(int x)
{
	int num=0;
	while(pre[x])
	{
		num++;
		x=pre[x];
	}
	printf("%d\n",num*2);
}
void bfs()
{
	if(n==k){printf("0");return ;}
	int head=0,tail=1;
	que[1]=n;
	mark[n]=true;
	while(head!=tail)
	{
		head++;
		for(int i=0;i<4;i++)
		{
			if(i==0) next=que[head]+1;
			if(i==1) next=que[head]-1;
			if(i==2) next=que[head]*2;
			if(i==3&&que[head]%2==0) next=que[head]/2;
			if(next>=0&&next<=sb&&mark[next]!=true)
			{
				tail++;
				que[tail]=next;
				mark[next]=true;
				pre[tail]=head;
				if(next==k) 
				{
					print(tail);
					head=tail;
					break;
				}
			}
		}
	}
}
int main()
{
	int QAQ;
	scanf("%d",&QAQ);
	for(int c=0;c<QAQ;c++)
	{
		scanf("%d%d",&n,&k);
		bfs();
		memset(mark,false,sizeof(mark));
		memset(que,0,sizeof(que));
		memset(pre,0,sizeof(pre));
		next=0;
	}
}

奋斗

心得体会

其实可以把时光当做一个数轴,就像在抓住那头牛中把牛和农夫当做数轴上的点一样(只不过这个数轴没有负),输入5、17的图:



展开阅读全文

没有更多推荐了,返回首页