题目大意:给两个四位的素数 A,B,每次只允许变换一个数字,换完后的四位数也要求是素数,问几步能使 A 换成 B,无法换到输出 Impossible
解题思路:4 位数字,每位数字可以换成 0~9,粗糙看一下是40个入口的BFS。
剪枝:
1、千位不能为 0
2、不能换成自己
3、替换后的数字也要是素数
判定素数这边先打一个素数表
//素数打表
void isprime() {
memset(prime, true, sizeof(prime));
for (int i = 2; i <= sqrt(MAXN); i++)
for (int j = i+i; j <= MAXN; j+=i)
prime[j] = false;
}
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<cmath>
#include<string.h>
#include<queue>
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
const int INF = 0x3f3f3f3f;
const int NINF = -INF -1;
const int MAXN = 10000+10;
using namespace std;
bool prime[MAXN], vis[MAXN];
int cnt[MAXN];
queue<int> q;
int T, a, b;
bool flag;
void isprime() {
memset(prime, true, sizeof(prime));
for (int i = 2; i <= sqrt(MAXN); i++)
for (int j = i+i; j <= MAXN; j+=i)
prime[j] = false;
}
void bfs(int cur, int tag) {
if (cur == tag) {
flag = true;
return;
}
q.push(cur);
vis[cur] = true;
int dig[4];
while (!q.empty()) {
int now = q.front();
q.pop();
// printf("%d\n", now);
dig[0] = now/1000;
dig[1] = now%1000/100;
dig[2] = now%100/10;
dig[3] = now%10;
for (int i = 0; i < 4; i++) {
int tmp = dig[i];
for (int j = 0; j < 10; j++) {
if (i == 0 && j == 0) continue;
if (j != tmp) {
dig[i] = j;
int num = dig[0]*1000+dig[1]*100+dig[2]*10+dig[3];
if (!vis[num] && prime[num]) {
cnt[num] = cnt[now] + 1;
q.push(num);
vis[num] = true;
}
if (num == b) {
flag = true;
return;
}
}
}
dig[i] = tmp;
}
}
}
int main() {
isprime();
scanf("%d", &T);
while (T--) {
scanf("%d%d", &a, &b);
memset(vis, 0, sizeof(vis));
memset(cnt, 0, sizeof(cnt));
flag = false;
while (!q.empty()) q.pop();
bfs(a, b);
if (flag) printf("%d\n", cnt[b]);
else printf("Impossible\n");
}
return 0;
}