题目描述
发明一种方案,把一个四位数质数变到另一个四位数质数,路径中每次只改变一个数字,每次改变后的四位数也是质数。
一个数字的价格是一磅,找到在两个给定的四位数素数之间最便宜的素数路径,第一位必须为非零。
例如1033->8179的质数路径:
1033->1733->3733->3739->3779->8779->8179
该解决方案的成本为6磅。
请注意,在步骤2中粘贴的数字1不能在最后一步中重复使用-必须购买新的1。
输入
一行带有正数:测试用例的数量(最多100个)。然后,对于每个测试用例,用两个数字用空格分隔的一行。
这两个数字都是四位数的质数(无前导零)。
输出
每种情况只用一行,或者用数字表示最低费用,或包含“Impossible”一词。
样本输入
3 1033 8179 1373 8017 1033 1033
样本输出
6 7 0
题目思路
将初始的四位数拆分成各个位数上的数字a,b,c,d,分别为千位、百位、十位、个位。
据题意可知,千位数不可为0,所以在千位数替换时从 1-9,替换的数字不能为原数字。
其他位数则可以选取 0-9 之间的数字替换。
替换之后,再将各个数字乘位数得到新的四位数检查是否为质数,且必须是之前没有变换到的数(用vis[]数组检查状态)。
如果满足这两个条件则可以入队,花费+1,继续下一次替换直到替换到终态。
代码如下:
#include<queue> #include<iostream> #include<cstdio> #include<cstring> #define fio ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); using namespace std; struct node { int num; int ans; }t1, t2; int t, start, e, flag; queue<node> q; bool vis[10005]; int check(int n) { if (n <= 1) return 0; for (int i = 2; i*i <= n; i++) if (n%i == 0) return 0; return 1; } void bfs(int start, int e) { t1.num = start; t1.ans = 0; vis[t1.num] = 1; q.push(t1); while (!q.empty()) { t1 = q.front(); q.pop(); int temp,a,b,c,d; for (int i = 0; i < 4; i++) { d = t1.num%10;c = t1.num/10%10; b = t1.num/100%10; a = t1.num/1000; if (i == 0) { for(int j = 1; j <= 9; j++) { if (j != a) { temp = j*1000+b*100+c*10+d; if (check(temp) && !vis[temp]) { t2.num = temp; t2.ans = t1.ans+1; if (t2.num == e) { flag = 1; printf("%d\n", t2.ans); return; } vis[t2.num] = 1; q.push(t2); } } } } if (i == 1) { for (int j = 0; j <= 9; j++) { if (j != b) { temp = a*1000+j*100+c*10+d; if (check(temp) && !vis[temp]) { t2.num = temp; t2.ans = t1.ans+1; if (t2.num == e) { flag = 1; printf("%d\n", t2.ans); return; } vis[t2.num] = 1; q.push(t2); } } } } if (i == 2) { for (int j = 0; j <= 9; j++) { if (j != c) { temp = a*1000+b*100+j*10+d; if (check(temp) && !vis[temp]) { t2.num = temp; t2.ans = t1.ans+1; if (t2.num == e) { flag = 1; printf("%d\n", t2.ans); return; } vis[t2.num] = 1; q.push(t2); } } } } if (i == 3) { for (int j = 0; j <= 9; j++) { if (j != d) { temp = a*1000+b*100+c*10+j; if (check(temp) && !vis[temp]) { t2.num = temp; t2.ans = t1.ans+1; if (t2.num == e) { flag = 1; printf("%d\n", t2.ans); return; } vis[t2.num] = 1; q.push(t2); } } } } } } } int main() { scanf("%d", &t); while (t--) { scanf("%d%d", &start, &e); memset(vis, 0, sizeof(vis)); while (!q.empty()) q.pop(); if (start == e) { printf("0\n"); } else { flag = 0; bfs(start, e); if (flag == 0) printf("Impossible\n"); } } }
ac,如果有错误请各位大佬指出~