题意:给定两个四位素数作为终点和起点,每次可以改变起点数的某一位,且改变后的数仍然是素数,问是否可能变换成终点数字?
思路:bfs搜索,每次改变四位数中的某一位。素数打表方便判断新生成的数是否是素数。
AC代码
#include<cstdio> #include<cstring> #include<queue> #include<cmath> using namespace std; const int maxn = 1e5 + 5; int vis[maxn], d[maxn]; void deal(int n){ int m = sqrt(n + 0.5); memset(vis, 0, sizeof(vis)); for(int i = 2; i <= m; ++i) if(!vis[i]) for(int j = i*i; j <= n; j += i) vis[j] = 1; } int x, y; void cut(int n, int *a) { int ind = 3; while(n > 0) { a[ind--] = n % 10; n /= 10; } } int rev(int *a) { int n = 0; for(int i = 0; i < 4; ++i) n = n * 10 + a[i]; return n; } int bfs() { memset(d, -1, sizeof(d)); d[x] = 0; queue<int>q; q.push(x); while(!q.empty()) { int n = q.front(); q.pop(); if(n == y) return d[y]; int a[4]; cut(n, a); for(int i = 0; i < 4; ++i){ int b[4]; memcpy(b, a, sizeof(b)); for(int j = 0; j <= 9; ++j) { b[i] = j; int num = rev(b); if(num > 10000 || num < 1000 || vis[num] || d[num] != -1) continue; d[num] = d[n] + 1; q.push(num); } } } return -1; } int main(){ deal(maxn); int T; scanf("%d", &T); while(T--) { scanf("%d%d", &x, &y); int ans = bfs(); if(ans == -1) printf("Impossible\n"); else printf("%d\n", ans); } return 0; }
如有不当之处欢迎指出!