題目大意:給定兩個四位素數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 }