poj3126:http://poj.org/problem?id=3126
题意:给你两个数n,k,两个数都是四位数的素数。现在让你改变n的一位数,让n变成另外一个素数。然后把这个素数在改变其中的以为又变成一个新的素数,问你最少有这样变换几步,才能使得使他变成k。
题解:求最短的问题,很自然的就想到了BFS,此外这一题还要处理10000以内的素数,可以采用素数筛法。
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<queue> using namespace std; int prime[100001];//标记该数是不是素数 struct Node{ int x; int step; }; int counts[10002]; int n,k; void DealPrime(){//素筛 memset(prime,1,sizeof(prime)); for(int i=2;i<=10000;i++){ if(prime[i]) for(int j=2*i;j<=10000;j+=i) prime[j]=0; } } int BFS(int x){ queue<Node>Q; for(int i=999;i<=10000;i++) counts[i]=10000000; Node tt; tt.x=x; tt.step=0; Q.push(tt); counts[x]=0; while(!Q.empty()){ Node temp=Q.front(); Q.pop(); int xx=temp.x; int a=xx%10;//取出个位 int b=xx/10%10;//十位 int c=xx/100%10;//百位 int d=xx/1000;//千位 int step=temp.step; for(int i=0;i<=9;i++){//个位的变换 int xxx=d*1000+c*100+b*10+i; if(prime[xxx]&&counts[xxx]>step+1){ counts[xxx]=step+1; Node t; t.x=xxx; t.step=step+1; Q.push(t); } } for(int i=0;i<=9;i++){//十位的变换 int xxx=d*1000+c*100+i*10+a; if(prime[xxx]&&counts[xxx]>step+1){ counts[xxx]=step+1; Node t; t.x=xxx; t.step=step+1; Q.push(t); } } for(int i=0;i<=9;i++){//百位的变换 int xxx=d*1000+i*100+b*10+a; if(prime[xxx]&&counts[xxx]>step+1){ counts[xxx]=step+1; Node t; t.x=xxx; t.step=step+1; Q.push(t); } } for(int i=1;i<=9;i++){//千位的变换,注意千位不能为0 int xxx=i*1000+c*100+b*10+a; if(prime[xxx]&&counts[xxx]>step+1){ counts[xxx]=step+1; Node t; t.x=xxx; t.step=step+1; Q.push(t); } } } return counts[k]; } int main(){ int cas; scanf("%d",&cas); DealPrime(); while(cas--){ scanf("%d%d",&n,&k); int ans=BFS(n); if(ans==10000000) printf("Impossible "); else printf("%d ",ans); } }