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)); //数组初始化
}
}