题目
思路
这道题目就是寻找一个四位素数到另一个四位素数的最小改变次数,每次只能改变一个数字,且改过后的数仍然是素数,分析过后就简单了,首先打一张素数表,然后我们再通过bfs改变位数,直到变为最终数字,记录步数,改变的时候枚举0-9每一位数字就可以了(个位可以只枚举奇数,千位不能存在0)。
题解
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
using namespace std;
struct num
{
int shu;
int time;
};
int a,b,ans;
const int MAXN=10000;
bool biao[MAXN];
bool notprime[MAXN];//值为 false 表示素数,值为 true 表示非素数
void init(){
memset(notprime,false,sizeof(notprime));
notprime[0]=notprime[1]=true;
for(int i=2;i<MAXN;i++)
if(!notprime[i]){
if(i>MAXN/i)continue;
for(int j=i*i;j<MAXN;j+=i)
notprime[j]=true;
}
}
void bfs()
{
if(a==b)
{
ans=0;
return;
}
queue<num> q;
num p;
p.shu=a;
p.time=0;
q.push(p);
while(!q.empty())
{
num pan;
pan=q.front();
q.pop();
if(pan.shu==b)
{
ans=pan.time;
return;
}
int x,y;
for(int i=1;i<=9;i+=2)
{
x=pan.shu;y=pan.time;
x=x/10;
x=x*10+i;
if(!notprime[x]&&!biao[x])
{
biao[x]=1;
num l;
l.shu=x;
l.time=y+1;
q.push(l);
}
}
for(int i=0;i<=9;i++)
{
x=pan.shu;y=pan.time;
int yu=x%10;
x=x/100;
x=x*10+i;
x=x*10+yu;
if(!notprime[x]&&!biao[x])
{
biao[x]=1;
num l;
l.shu=x;
l.time=y+1;
q.push(l);
}
}
for(int i=0;i<=9;i++)
{
x=pan.shu;y=pan.time;
int yu=x%100;
x=x/1000;
x=x*10+i;
x=x*100+yu;
if(!notprime[x]&&!biao[x])
{
biao[x]=1;
num l;
l.shu=x;
l.time=y+1;
q.push(l);
}
}
for(int i=1;i<=9;i++)
{
x=pan.shu;y=pan.time;
int yu=x%1000;
x=i*1000+yu;
if(!notprime[x]&&!biao[x])
{
biao[x]=1;
num l;
l.shu=x;
l.time=y+1;
q.push(l);
}
}
}
}
int main()
{
int t;
scanf("%d",&t);
init();
while(t--)
{
memset(biao,0,sizeof(biao));
cin>>a>>b;
bfs();
cout<<ans<<endl;
}
return 0;
}