题目大意:给定两个四位素数a b,要求把a变换到b,变换的过程要保证 每次变换出来的数都是一个 四位素数,并且当前这步的变换所得的素数 与 前一步获得的素数 只能有一个位不一样,并且每步获得的素数都不能重复。ios
题目连接:点击打开连接spa
分析:分析可知这题确定是用搜索,每次改变某位,每位有0-9(首位无0)10种变法,一共40个方向,但是到底DFS仍是BFS仍是二分呢?只二分对这题显然是不太好写的,DFS的话复杂度为O(40^n)估计几年也出不告终果来,,,而后BFS的话O(40*n)确定是能够过的。BFS是很好写,麻烦的就在数字的转变和素数的判断。这里素数的判断因为是多组数据咱们能够用埃式筛选打一个表(怎么实现能够直接看代码,本身思考下就好了,这里朴素的方法也是能够过的)。对于改变一个数字的某一位咱们能够用到sprintf和sscanf这2个黑科技来简单的实现,只要先把初始数字用sprintf打印到字符串里,而后利用字符串的随机访问来改变其中某一位就好了,接下来再用sscanf再输出到temp1中便可。code
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 using namespace std; 6 #define N 100005 7 8 bool prime[N],mark[N]; 9 int in,out; 10 11 void bfs() 12 { 13 int i,j; 14 queue<int> q; 15 queue<int> a;//存步数 16 17 memset(mark,0,sizeof(mark)); 18 q.push(in); 19 a.push(0); 20 mark[in]=1; 21 while (!q.empty()) 22 { 23 int temp=q.front(); 24 int ta=a.front(); 25 q.pop(); 26 a.pop(); 27 if (temp==out) 28 { 29 printf("%d\n",ta); 30 return;//出口记得return!!! 31 } 32 for (i=0;i<4;i++) 33 { 34 for (j=0;j<=9;j++) 35 { 36 if (0==i&&0==j)//是千位不能为0,因此是0==i&&0==j!!! 37 { 38 continue; 39 } 40 char s[6]="\0"; 41 sprintf(s,"%d",temp); 42 s[i]=j+'0'; 43 int temp1; 44 sscanf(s,"%d",&temp1);//新数要新的变量存储,不能用temp!!! 45 if (prime[temp1]&&!mark[temp1]) 46 { 47 q.push(temp1); 48 mark[temp1]=1; 49 a.push(ta+1); 50 } 51 } 52 } 53 } 54 printf("Impossible\n"); 55 } 56 57 void cprime()//打素数表 58 { 59 int i,j; 60 memset(prime,true,sizeof(prime)); 61 prime[0]=prime[1]=false; 62 for (i=2;i<N;i++) 63 { 64 if (prime[i]) 65 for (j=2*i;j<N;j=j+i) 66 { 67 prime[j]=false; 68 } 69 } 70 } 71 72 int main() 73 { 74 int t; 75 76 cprime(); 77 scanf("%d",&t); 78 while (t--) 79 { 80 scanf("%d %d",&in,&out); 81 bfs(); 82 } 83 84 return 0; 85 }