// 600K 16MS G++
#include <cstdio>
#include <queue>
#include <cstring>
#include <cmath>
using namespace std;
char compositeNum[10000];
char BFSFlag[10000];
void getPrime() {
int max = 100;
int begin = 2;
while(begin <= 100) {
for (int i = begin + 1; i <= 9999; i++) {
if (i%begin == 0) {
compositeNum[i] = 1;
}
}
for (int i = begin + 1; i <= 999; i++) {
if (compositeNum[i] == 0) {
begin = i;
break;
}
}
}
}
int sNum;
int tNum;
struct BFSNode {
int num;
int roundNum;
};
typedef struct BFSNode BFSNode;
queue<BFSNode> BFSQueue;
int BFS() {
while(BFSQueue.size()) {
BFSQueue.pop();
}
memset(BFSFlag, 0, sizeof(BFSFlag));
BFSNode beignNode;
beignNode.num = sNum;
beignNode.roundNum = 0;
BFSQueue.push(beignNode);
BFSFlag[sNum] = 1;
while(BFSQueue.size()) {
BFSNode curNode = BFSQueue.front();
BFSQueue.pop();
int curNum = curNode.num;
int curRoundNum = curNode.roundNum;
//1
for (int i = 1; i <= 9; i++) {
int newVal = i*1000 + curNum%1000;
if (!compositeNum[newVal]) {
if (newVal == tNum) {
return curRoundNum+1;
} else {
if (!BFSFlag[newVal]) {
BFSFlag[newVal] = 1;
BFSNode newNode;
newNode.num = newVal;
newNode.roundNum = curRoundNum + 1;
BFSQueue.push(newNode);
}
}
}
}
//2
for (int i = 0; i <= 9; i++) {
int newVal = curNum/1000 * 1000 + i*100 + curNum%100;
if (!compositeNum[newVal]) {
if (newVal == tNum) {
return curRoundNum+1;
} else {
if (!BFSFlag[newVal]) {
BFSFlag[newVal] = 1;
BFSNode newNode;
newNode.num = newVal;
newNode.roundNum = curRoundNum + 1;
BFSQueue.push(newNode);
}
}
}
}
//3
for (int i = 0; i <= 9; i++) {
int newVal = curNum/100 * 100 + i*10 + curNum %10;
if (!compositeNum[newVal]) {
if (newVal == tNum) {
return curRoundNum+1;
} else {
if (!BFSFlag[newVal]) {
BFSFlag[newVal] = 1;
BFSNode newNode;
newNode.num = newVal;
newNode.roundNum = curRoundNum + 1;
BFSQueue.push(newNode);
}
}
}
}
//4
for (int i = 0; i <= 9; i++) {
int newVal = curNum/10*10 + i;
if (!compositeNum[newVal]) {
if (newVal == tNum) {
return curRoundNum+1;
} else {
if (!BFSFlag[newVal]) {
BFSFlag[newVal] = 1;
BFSNode newNode;
newNode.num = newVal;
newNode.roundNum = curRoundNum + 1;
BFSQueue.push(newNode);
}
}
}
}
}
return -1;
}
void solve() {
printf("%d\n", BFS());
}
int main() {
memset(compositeNum, 0, sizeof(compositeNum));
getPrime();
// for (int i = 9000; i < 10000; i++) {
// if (!compositeNum[i]) {
// printf("%d\n", i);
// }
// }
int caseNum;
scanf("%d\n", &caseNum);
for (int i = 1; i <= caseNum; i++) {
scanf("%d %d", &sNum, &tNum);
if (sNum == tNum) {
printf("0\n");
} else {
solve();
}
}
}
算是一道数论 + BFS水题。
解题之前先用素数筛子筛一遍1~10000的数,搞一个bitmap数组标示素数和非素数。
然后就简单了,BFS从给的数开始,每次有9(第一位不能是0)*10*10*10个选择,不过因为 有BFSFlag标示和可能不是素数,因此其实最后的运算量不大,
最差就是把1000~9999的数全过一遍,以遇到要转的素数结束BFS。BFSNode带上round次数,最后输出。