题目:
http://poj.org/problem?id=3126题意:
给出两个素数求二者之间转换的最小步骤数,要求两个只有一位不相同的素数可以互相转换。
同时给定素数都是4位数。如果不能转换输出Impossible。
思路:
简单的搜索题,最近搜索总不能一遍过,所以写一下写一下,,
因为只有4位数的素数,直接筛素数打表出有1061个素数。
之后bfs从一个搜到另一个就行了,只要注意更新vis[]保证每个数只搜一遍就不会tle,
另外提一下 忘了写Impossible也ac了,可能是4位数所有素数之间都可以转换吧,具体原因不详。
代码:
#define N 11234
#define M 1123
int n,m;
int flag,sum,ave,ans,res,len,ans1,ans2;
int g[M][M];
bool vis[N];
struct node
{
int x,y;
}tn;
bool mark[N];
int pri[N];
int cnt;
void SP()
{
cnt=0;
memset(mark,true,sizeof(mark));
mark[0]=mark[1]=false;
for(int i=2;i*i<=N;i++)
if(mark[i])
for(int j=2;j*i<N;j++)
mark[j*i]=false;
for(int i=0;i<N;i++)
if(mark[i]&&i>999&&i<10000)
pri[cnt++]=i;
}
bool check(int x,int y)
{
flag=0;
int t=1;
for(int k=0;k<4;k++)
{
if(x/t%10!=y/t%10)
flag++;
t*=10;
}
if(flag==1)
return true;
return false;
}
bool solve()
{
int i,j,k,t;
node h,p;
queue<node> q;
while(!q.empty())q.pop();
h.x=n;h.y=0;
q.push(h);
memset(vis,false,sizeof(vis));
vis[n]=true;
while(!q.empty())
{
h=q.front();q.pop();
if(h.x==m)
{
printf("%d\n",h.y);
return true;
}
for(i=0;i<cnt;i++)
if(!vis[pri[i]]&&check(h.x,pri[i]))
{
p.x=pri[i];p.y=h.y+1;
vis[pri[i]]=true;
q.push(p);
}
}
return false;
}
int main()
{
int i,j,k,kk,t,x,y,z;
SP();
scanf("%d",&k);
while(k--)
{
scanf("%d%d",&n,&m);
if(!solve())
printf("Impossible\n");
}
return 0;
}