POJ - 3126 链接
题目大意就是给定两个都是4位数的质数,每次改变一位数字,把数字a 变成数字b 的最短步数, 同时要满足在变换的过程中数字一定严格满足是是质数。
思路,先用素数筛筛选出所有4位数质数,
然后,最短路嘛,bfs没跑了,这里要做的就是枚举改变每一位的状态,注意第一位不能变成0。
//Powered by CK
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
typedef pair<int, int> PII;
const int N = 1e5 + 10;
int prime[N], cnt = 0, a, b;
bool st[N], visit[N];
void init() {//素数筛,筛完后st数组下标是素数的将会是false,非素数是true
for(int i = 2; i < N; i++) {
if(!st[i]) prime[cnt++] = i;
for(int j = 0; j < cnt && prime[j] * i < N; j++) {
st[prime[j] * i] = true;
if(i % prime[j] == 0) break;
}
}
}
int main() {
// freopen("in.txt", "r", stdin);
init();
int t;
cin >> t;
while(t--) {
cin >> a >> b;
memset(visit, false, sizeof visit);
queue<PII> q;
q.push(make_pair(a, 0));
visit[a] = true;
while(!q.empty()) {
PII temp = q.front();
q.pop();
if(temp.first == b) {
cout << temp.second << endl;
break;
}
for(int i = 1; i < 10; i++) {//改变第一位
int f = temp.first % 1000 + i * 1000;
if(!visit[f] && !st[f]) {
q.push(make_pair(f, temp.second + 1));
visit[f] = true;
}
}
for(int i = 0; i < 10; i++) {//改变第二位
int f = temp.first / 1000 * 1000 + i * 100 + temp.first % 100;
if(!visit[f] && !st[f]) {
q.push(make_pair(f, temp.second + 1));
visit[f] = true;
}
}
for(int i = 0; i < 10; i++) {//改变第三位
int f = temp.first / 100 * 100 + i * 10 + temp.first % 10;
if(!visit[f] && !st[f]) {
q.push(make_pair(f, temp.second + 1));
visit[f] = true;
}
}
for(int i = 0; i < 10; i++) {//改变第四位
int f = temp.first / 10 * 10 + i;
if(!visit[f] && !st[f]) {
q.push(make_pair(f, temp.second + 1));
visit[f] = true;
}
}
}
}
return 0;
}