1. 程式人生 > 實用技巧 >Prime Path(BFS)

Prime Path(BFS)

原題連結

我太菜了。。。

發現每次寫完一個題的程式碼就要改好久。。。

這道題由於要求花費最少的路線值,考慮到BFS在這種問題下

的便利性,因此打算使用BFS演算法,那麼如何考慮這道題呢?

首先將題目分解成一個一個的小問題,它們分別是求出四位數

裡面的素數,判斷兩個數是否只相差一個數字,當然還要有個

布林陣列來判斷某一個數字是否使用過,這樣就能夠減少不必要的

訪問。

需要注意的是,每次將一個數放到佇列裡後,下次迴圈就要從

四位素數表裡的最小的那一位重新開始遍歷,因為會有從後往前

判斷的情況,例如樣例裡面8779 -> 8179。

 1 #include <iostream>
 2
#include <cstring> 3 #include <queue> 4 #include <algorithm> 5 using namespace std; 6 const int N = 10000; 7 int index = 0, prime[N]; 8 bool is_prime[N], vis[N]; 9 struct node{ 10 int x, d; 11 node(int xx, int dd){ 12 x = xx, d = dd; 13 } 14 }; 15 queue<node> q;
16 void prime_shieve(){ //埃氏素數篩 17 memset(is_prime, true, sizeof(is_prime)); 18 for(int i = 2; i <= 9999; i ++){ 19 if(is_prime[i]){ 20 prime[++ index] = i; 21 for(int j = i * 2; j <= 9999; j += i) 22 is_prime[j] = false; 23 }
24 } 25 } 26 int find(int x){ //在所有四位數裡求某一個數字的vis下標 27 for(int i = 1; i <= index; i ++) 28 if(prime[i] == x) 29 return i; 30 } 31 bool check(int x, int i){ //判斷兩個數不同的位數,有三個相同則可以替換 32 int sum = 0; 33 if(x / 1000 == i / 1000) sum ++; 34 if(x / 100 % 10 == i / 100 % 10) sum ++; 35 if(x / 10 % 10 == i / 10 % 10) sum ++; 36 if(x % 10 == i % 10) sum ++; 37 return sum == 3; 38 } 39 int bfs(int s, int e){ 40 q.push(node(s, 0)); 41 while(!q.empty()){ 42 node now = q.front(); 43 q.pop(); 44 vis[now.x] = true; 45 if(now.x == e) 46 return now.d; 47 for(int i = find(1009); i <= index; i ++) 48 if(check(now.x, prime[i]) && !vis[prime[i]]){ 49 q.push(node(prime[i], now.d + 1)); 50 vis[prime[i]] = true; 51 } 52 } 53 return -1; 54 } 55 int main(){ 56 int start, end, t; 57 prime_shieve(); 58 cin >> t; 59 while(t --){ 60 cin >> start >> end; 61 memset(vis, 0, sizeof vis); 62 while(!q.empty()) q.pop(); 63 if(start == end) 64 cout << 0 << endl; 65 else{ 66 int ans = bfs(min(start, end), max(start, end)); 67 if(ans != -1) 68 cout << ans << endl; 69 else 70 cout << "Impossible" << endl; 71 } 72 } 73 return 0; 74 }