题目链接:Prime Path
解析:两个长度为4的数字s和e,操作定义为:每步只能改变一位数字,并且改变后的数字必须为素数。问s最少经历多少次操作能变成e。
先预处理筛出10000以内的素数
每次操作可以对4个数字中的一个操作
对于每个数字有10种可能性
AC代码:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
#include <string>
using namespace std;
string s, e;
bool vis[10000];
bool tg[10000];
void init(){ //筛素数
memset(tg, true, sizeof(tg));
for(int i=2; i<10000; i++){
if(!tg[i]) continue;
for(int j=i+i; j<10000; j+=i)
tg[j] = false;
}
tg[0] = tg[1] = false;
for(int i=0; i<1000; i++) tg[i] = false;
}
int bfs(){
queue<pair<string, int> > q;
q.push(make_pair(s, 0));
string tmp;
while(!q.empty()){
pair<string, int> now = q.front(); q.pop();
if(now.first == e) return now.second;
for(int k=0; k<4; k++){
for(int i=0; i<10; i++){
string tmp = now.first;
tmp[k] = i + '0';
int n = (tmp[0] - '0')*1000 + (tmp[1] - '0')*100 + (tmp[2] - '0')*10 + (tmp[3] - '0');
if(!vis[n] && tg[n]){
vis[n] = true;
q.push(make_pair(tmp, now.second+1));
}
if(tmp == e) return now.second+1;
}
}
}
return -1;
}
int main(){
#ifdef sxk
freopen("in.txt", "r", stdin);
#endif //sxk
init();
int t, n;
scanf("%d", &t);
while(t--){
cin>>s>>e;
memset(vis, 0, sizeof(vis));
printf("%d\n", bfs());
}
return 0;
}