///BFS,因为每次只是变换一个数位,这样就有四种选择,相当于一个四叉树,而在每一分支里 ///又可以分成最多十支,vis数组保存最后得到的结果。若vis[k]为-1,则说明没有变换到目标 ///的方法,否则为目标值。 程序中也利用了vis数组来判断重复。写出分析重点,好好体味一下 ///BFS题目的特点。 可以进行适当的剪枝,也可以不用STL中的queue,因为它实在是太慢了 #include<stdio.h> #include<string.h> #include<math.h> #include<queue> using namespace std; int vis[10000]; int s,d; queue<int> q; int isprime(int k) { int i,p=(int)sqrt((double)k);//注意sqrt函数的返回值和参数类型,否则compile error for(i=3;i<=p;i++) { if(k%i==0) return 0; } return 1; } int change(int num,int x,int y) { if(x==1&&y==0) return -1; if(x==4&&(y%2==0)) return -1; int t; if(x==1) t=num%1000+y*1000; else if(x==2) t=num/1000*1000+num%100+y*100; else if(x==3) t=num/100*100+num%10+y*10; else t=num/10*10+y; if(t==num) return -1; if(vis[t]!=-1) return -1; if(isprime(t)) return t; else return -1; } int bfs() { vis[s]=0; q.push(s); while(!q.empty()) { int t=q.front(),i,j; q.pop(); for(i=1;i<=4;i++) { for(j=0;j<10;j++) { int res=change(t,i,j); if(res<0)continue; if(vis[res]==-1) vis[res]=vis[t]+1; else continue; if(res==d) return 0; q.push(res); } } } } int main() { int cas; scanf("%d",&cas); while(cas--) { scanf("%d%d",&s,&d); memset(vis,-1,sizeof(vis)); if(s==d) vis[d]=0; else bfs(); if(vis[d]==-1) printf("Impossible/n"); else printf("%d/n",vis[d]); while(!q.empty())///注意对上一组数据进行扫尾,即清空队列中遗留元素 q.pop(); ///不然会影响下一组数据的结果。 } }