思路:BFS思想,逐一由千位变到个位,每一位由1变到9,没变一次,比对这个数是不是素数,如果是就将它保存到队列中,循环里每次处理的都是上一个数,这才是广搜的核心。再使用一个一维数组,用变化后的素数表示下标,用它对应的值来表示所要进行的步数。
先将1000到10000的所有素数都求出来保存到一个一维数组中(下标对应值为1),下标不是素数值为0.
AC代码(c++)
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <map>
#include <string>
#include <deque>
#include <queue>
#include <cstdio>
#include <cstdlib>
#include <set>
using namespace std;
#include <queue>
int vis[1000000];
int a[100000];
struct node
{
int x;
int time;
} start,now,ff;
queue<node>q;
void f(int x, int time) //寻找符合条件的素数
{
int w,b,c,d;
w=x%10;
b=x/10%10;
c=x/100%10;
d=x/1000;
for(int i=0; i<=9; i++)
{ int y;
if(w!=i)
{
y=d*1000+c*100+b*10+i;
if(a[y]==0&&y>=1000&&vis[y]==0)
{
vis[y]=1;
ff.x=y;
ff.time=time+1;
q.push(ff);
}
}
if(b!=i)
{
y=d*1000+c*100+w+i*10;
if(a[y]==0&&y>=1000&&vis[y]==0)
{
vis[y]=1;
ff.x=y;
ff.time=time+1;
q.push(ff);
}
}
if(c!=i)
{
y=d*1000+i*100+b*10+w;
if(a[y]==0&&y>=1000&&vis[y]==0)
{
vis[y]=1;
ff.x=y;
ff.time=time+1;
q.push(ff);
}
}
if(d!=i)
{
y=i*1000+c*100+b*10+w;
if(a[y]==0&&y>=1000&&vis[y]==0)
{
vis[y]=1;
ff.x=y;
ff.time=time+1;
q.push(ff);
}
}
}
}
int bfs(int x,int y) //搜索函数
{
start.x=x;
start.time=0;
vis[x]=1;
q.push(start);
while(!q.empty())
{
now=q.front();
q.pop();
if(now.x==y)
return now.time;
f(now.x,now.time);
}
}
int main()
{
memset(a,0,sizeof (a));
for(int i=2; i<=10000; i++) //素筛
{
if(a[i]==0)
{
for(int j=i*i; j<=10000; j+=i)
{
a[j]=1;
}
}
}
int t;
cin>>t;
while(t--)
{
memset(vis,0,sizeof (vis));
while(!q.empty())
q.pop();
int x,y;
cin>>x>>y;
int ans=bfs(x,y);
cout<<ans<<endl;
}
return 0;
}