题目链接:https://cn.vjudge.net/problem/POJ-3126
注意:预处理1000-9999间的素数,并且对入过队列的数进行标记,防止重复入队,否则超时
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <queue> 5 #include <algorithm> 6 #include <cmath> 7 #define mem(a,b) memset(a,b,sizeof(a)); 8 using namespace std; 9 #define INF 0x3f3f3f3f 10 typedef long long ll; 11 int dir[4][2] = {0,1,0,-1,1,0,-1,0}; 12 const int maxn = 100005; 13 int n,m,a[10005],vis[10005];//a数组标记是否为素数,vis数组标记是否入过队列 14 struct node 15 { 16 int x,y;//x存当前的数,y存 到这个数的花费 17 node(int xx,int yy):x(xx),y(yy) {}; 18 }; 19 queue<node>q; 20 void judge()//预处理1000-9999间的素数 21 { 22 int i,k; 23 for(int j = 1000; j <= 9999; j++) 24 { 25 k = sqrt(j); 26 for(i = 2; i <= k; i++) 27 { 28 if(j % i == 0) 29 break; 30 31 } 32 if(i == k+1) 33 a[j] = 1; 34 } 35 36 37 } 38 void bfs(int p) 39 { 40 q.push(node(p,0)); 41 while(!q.empty()) 42 { 43 node k = q.front(); 44 q.pop(); 45 if(k.x == m) 46 { 47 cout << k.y << endl; 48 break; 49 } 50 int k1 = k.x/1000%10, k2 = k.x/100%10, k3 = k.x/10%10, k4 = k.x%10;//k1,k2,k3,k4分别存千位,百位,十位,个位 51 int temp; 52 //每一次只能改变一位 53 for(int i = 1; i <= 9; i++)//改变千位上的数,不能为0 54 { 55 if(i == k1) continue; 56 int kk1 = i; 57 temp = kk1*1000+k2*100+k3*10+k4; 58 if(a[temp] == 1&&!vis[temp])//判断该数是否为素数以及是否重复入队 59 { 60 vis[temp] = 1; 61 q.push(node(temp,k.y+1)); 62 } 63 } 64 for(int i = 0; i <= 9; i++)//改变百位上的数 65 { 66 if(i == k2) continue; 67 int kk2 = i; 68 temp = k1*1000+kk2*100+k3*10+k4; 69 if(a[temp] == 1&&!vis[temp]) 70 { 71 vis[temp] = 1; 72 q.push(node(temp,k.y+1)); 73 } 74 } 75 for(int i = 0; i <= 9; i++)//改变十位上的数 76 { 77 if(i == k3) continue; 78 int kk3 = i; 79 temp = k1*1000+k2*100+kk3*10+k4; 80 if(a[temp] == 1&&!vis[temp]) 81 { 82 vis[temp] = 1; 83 q.push(node(temp,k.y+1)); 84 } 85 } 86 for(int i = 0; i <= 9; i++)//改变个位上的数 87 { 88 if(i == k4) continue; 89 int kk4 = i; 90 temp = k1*1000+k2*100+k3*10+kk4; 91 if(a[temp] == 1&&!vis[temp]) 92 { 93 vis[temp] = 1; 94 q.push(node(temp,k.y+1)); 95 } 96 } 97 } 98 } 99 int main() 100 { 101 int t; 102 cin >> t; 103 judge();//预处理 104 while(t--) 105 { 106 mem(vis,0); 107 while(!q.empty()) 108 q.pop();//每次使用的时候都清空一次,防止上次使用队列没有清空 109 cin >> n >> m; 110 bfs(n); 111 } 112 return 0; 113 }