Prime Path(用queue写广搜)

题目:

给你两个四位的素数 a,ba,b 。
 aa 可以改变某一位上的数字变成 cc ,但只有当 cc 也是四位的素数时才能进行这种改变。
请你计算 aa 最少经过多少次上述变换才能变成 bb 。
例如:1033 -> 8179 
1033 
1733 
3733 
3739 
3779 
8779 
8179
最少变换了6次。

输入格式

第一行输入整数 TT ,表示样例数。 (T \le 100)(T≤100)
每个样例输入两个四位的素数 a, ba,b 。(没有前导零) 

输出格式

对于每个样例,输出最少变换次数,如果无法变换成 bb 则输出"Impossible"。

注意:仅对于此题,输出时每行末尾的多余空格,不影响答案正确性。

输入样例

3
1033 8179
1373 8017
1033 1033

输出样例

6
7
0

这道题相当于广搜的四个方向,即把四位数的每个数位走一遍,先把四位的素数打个表再写

代码:

#include<stdio.h>
#include<string.h>
#include<queue>
#define N 10100
using namespace std;
int n,st,en;
bool book[N];
bool ss[N];
struct node {
	int step;
	int num;
};
void init() // 素数打表 
{
	for(int i=2; i<10000; i++) {
		if(ss[i])continue;
		for(int j=i+i; j<10000; j+=i) {
			ss[j]=true;
		}
	}
}
void bfs() 
{
	memset(book,0,sizeof(book));
	queue<node>q;
	node x;
	//存开始的那个数即为“起点” 
	x.num=st;
	x.step=0;//此时步数即变换次数为0 
	book[x.num]=true;//标记已经走过 
	q.push(x);//存入队列 
	while(!q.empty()) 
	{
		//把队列中的元素提出来并清除 
		node x=q.front();
		q.pop();
		if(x.num==en) //如果已经找到或着说到达要变幻的素数就输出此时步数 
		{
			printf("%d\n",x.step);
			return ;
		}
		for(int i=0; i<4; i++) //四位数每个数位都要从1到9走一遍 
		{
			for(int j=0; j<10; j++) 
			{
				if(!i&&!j)
					continue;
				node y;//y为x的下一步 
				y.step=x.step+1;
				
				int a=x.num/1000;
				int b=x.num%1000/100;
				int c=x.num%100/10;
				int d=x.num%10;
				if(i==0)
					a=j;
				else if(i==1)
					b=j;
				else if(i==2)
					c=j;
				else if(i==3)
					d=j;
				y.num=a*1000+b*100+c*10+d;
				//判断y这个数是不是素数 
				if(book[y.num]||ss[y.num])
					continue;
				book[y.num]=true;//标记走过 
				q.push(y);//存入队列方便下一次取出 
			}
		}
	}
}
int main() {
	init();
	scanf("%d",&n);
	while(n--) {
		scanf("%d%d",&st,&en);
		bfs();
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值