Prime Path

Prime Path

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

Input

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

Output

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

Sample Input

3
1033 8179
1373 8017
1033 1033

Sample Output

6
7
0

解题思路:题目的意思很简单,其实就是把一个四位数的每一位都换成0-9之中的数,如果是素数,
将这个数放入队列之中就行,当他能够变成最终的数时,输出次数即可

#include<stdio.h>
#include<queue>
#include<string.h>
using namespace std;

char s2[4];

int a[10005];

struct node
{

	char s1[4];		//使用字符型数组储存四位数 

	int steps;     //计次 

}NOW, NEXT;

int bfs(int steps)
{
	
	NOW.steps = steps;
	
	queue<node> q;
	
	q.push(NOW);
	
	while(!q.empty())
	{
		NOW = q.front();
		q.pop();
		for(int i = 0; i < 4; i++)         //分别变换每一个位置的数 
		{
			for(int j = 0; j < 10; j++)
			{
 				NEXT.s1[0] = NOW.s1[0];
				
				NEXT.s1[1] = NOW.s1[1];
				
				NEXT.s1[2] = NOW.s1[2];
				
				NEXT.s1[3] = NOW.s1[3];
				
				NEXT.s1[i] = '0' + j;            
				
				if(NEXT.s1[0] == s2[0] && NEXT.s1[1] == s2[1] && NEXT.s1[2] == s2[2] && NEXT.s1[3] == s2[3])//满足变换结果的数输出 
					
					return NOW.steps;
				
				if(NEXT.s1[i] == NOW.s1[i])//如果变换后的数和当前相等,代表变换重复了,进行下一次变换 
				
					continue;
				
				if(NEXT.s1[0] == '0')//首位不能变换成0 
					
					continue;
				int num = (NEXT.s1[0] - '0') * 1000 + (NEXT.s1[1] - '0') * 100 + (NEXT.s1[2] - '0') * 10 + NEXT.s1[3] - '0';
				
				if(a[num])  //判断新变换的数是否为素数 或者已经变过这个数了 
					
					continue;
				
				a[num] = 1;   //将变换过的数进行标记,下一次不会重复变换 
				
				NEXT.steps = NOW.steps + 1;//变换次数+1 
				
				q.push(NEXT);
			}
		}
	}
	return -1;
}
int main()
{
	int n;
	
	scanf("%d", &n);
	
	getchar();
	
	while(n--)
	{
		scanf("%s %s", NOW.s1, s2);
		
		for(int i = 2; i <= 400; i++)             //筛法求素数,将素数和非素数标记出来 
		{
			for(int j = i; j * i <= 10000; j++)
			
				if(!a[i * j])
					
					a[i * j] = 1;
		}
		
		if(NOW.s1[0] == s2[0] && NOW.s1[1] == s2[1] && NOW.s1[2] == s2[2] && NOW.s1[3] == s2[3])
			
			printf("0\n");
		
		else
		{
			int ans = bfs(0);
			
			printf("%d\n",ans + 1);
		}
		
		memset(a, 0, sizeof(a));              //数组初始化 
	}
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值