题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1973
题目大意:给定两个四位素数a b,要求把a变换到b变换的过程要保证 每次变换出来的数都是一个 四位素数,而且当前这步的变换所得的素数
与前一步得到的素数 只能有一个位不同,而且每步得到的素数都不能重复。求从a到b最少需要的变换次数。无法变换则输出Impossible。
如下面的样例:1033 8179
1033
1733
3733
3739
3779
8779
8179
1733
3733
3739
3779
8779
8179
所以答案为6。
解题思路:bfs,枚举变换个、十、百、千这四位,从0~9,是素数就入队,不断bfs直到找出答案。要注意千位不能为0!!!
1 #include<cstdio> 2 #include<queue> 3 #include<cstring> 4 using namespace std; 5 const int N=1e4+5; 6 7 int n,res,ans; 8 int vis[N]; 9 int Pow[4]={1,10,100,1000}; 10 bool prime[N]; 11 12 void is_prime(){ 13 for(int i=2;i<N;i++){ 14 prime[i]=true; 15 } 16 for(int i=2;i*i<N;i++){ 17 if(prime[i]){ 18 for(int j=i*i;j<N;j+=i) 19 prime[j]=false; 20 } 21 } 22 } 23 24 struct node{ 25 int step; 26 int num; 27 }pre,now; 28 29 bool bfs(){ 30 queue<node>q; 31 now.num=n; 32 now.step=0; 33 q.push(now); 34 while(!q.empty()){ 35 pre=q.front(); 36 q.pop(); 37 int x=pre.num; 38 //枚举四位,从0~9(千位不能为0),找出素数入队,不断bfs直到找出答案 39 for(int i=0;i<4;i++){ 40 for(int j=0;j<=9;j++){ 41 int t=x; 42 if(i==0) 43 t-=t%10*Pow[i]; 44 if(i==1) 45 t-=t%100/10*Pow[i]; 46 if(i==2) 47 t-=t%1000/100*Pow[i]; 48 if(i==3) 49 t-=t/1000*Pow[i]; 50 if(i==3&&j==0) 51 continue; 52 t+=j*Pow[i]; 53 if(t==x||!prime[t]||vis[t]) 54 continue; 55 if(t==res){ 56 ans=pre.step+1; 57 return true; 58 } 59 vis[t]=1; 60 now.num=t; 61 now.step=pre.step+1; 62 q.push(now); 63 } 64 } 65 } 66 return false; 67 } 68 69 int main(){ 70 is_prime(); 71 int t; 72 scanf("%d",&t); 73 while(t--){ 74 memset(vis,0,sizeof(vis)); 75 scanf("%d%d",&n,&res); 76 if(n==res){ 77 puts("0"); 78 continue; 79 } 80 ans=0; 81 if(bfs()) 82 printf("%d\n",ans); 83 else 84 puts("Impossible"); 85 } 86 return 0; 87 }