注意素数的判断算法不要马虎写错
BFS,AC代码如下:
#include<iostream>
#include<cstring>
using namespace std;
int vis[10000];//判断节点是否入队过
struct node
{ int parent;//为了寻找路径debug设置的父节点
int x;
int num;//开始访问本节点时的步数
} link[10000];
int cal[4]= {1000,100,10,1};
//int loc[4][10];//判断某一个数字能否重新被使用,0表示可以
int pp,qq;
int x1,x2;
int flag,minx;//标记访问成功或失败和最短步数
int n;
bool isPrime(int x,int ii,int jj)//将素数和合法写到同一个函数中
{
for(int i=3; i*i<=x; i=i+2)
{
if(x%i==0)
return false;
}
if(vis[x]==1)
return false;
//if(loc[ii][jj]==1)return false;
return true;
}
void bfs()
{
if(x1==x2)
{
flag=1;
minx=0;
return;
}
while(pp<qq)
{
for(int i=0; i<4; i++)
{
int m=cal[i];
int jj=(link[pp].x/m)%10;//第i+1位上的数字
for(int j=0; j<=9; j++) //改变第i+1位上的数字
{
if(j==jj||(i==0&&j==0)||(i==3&&j%2==0))
continue;
int xx=link[pp].x-jj*m+j*m;//改变数字完成
if(isPrime(xx,i,j))
{
if(xx==x2)
{ //设置最后一个节点但是不用入队
flag=1;
minx=link[qq].num=link[pp].num+1;
link[qq].x=x2;//尾节点
link[qq].parent=link[pp].x;
return;
}
else
{
//节点入队
link[qq].x=xx;
link[qq].num=link[pp].num+1;
link[qq].parent=link[pp].x;
qq++;
vis[xx]=1;
//loc[i][jj]=1;//已经消除的数字不能被使用
}
}
}
}
pp++;
}
}
int main()
{
cin>>n;
while(n--)
{
cin>>x1>>x2;//搜索起点和终点
memset(vis,0,sizeof(vis));
//memset(loc,0,sizeof(loc));
flag=0;
qq=pp=0;
vis[x1]=1;
link[qq].x=x1;
link[qq].num=0;
link[qq].parent=0;
qq++;//开始的节点入队
bfs();
int i=qq;
/*while(i)//i表示当前指针在没有到达0时
{cout<<link[i].x<<endl;
for(int x=0;x<i;x++)
if(link[x].x==link[i].parent)
{i=x;
break;
}
}*/
//cout<<x1<<endl;
if(flag)
cout<<minx<<endl;
else
cout<<"Impossible"<<endl;
}
return 0;
}