题目链接:http://poj.org/problem?id=3126
题目大意:给你一个四位数N 和 一个四位数M ,从 N -> M 每次只可以改变一个四位中的任何一位数,但是改变后的数必须是素数,问你最少可以经过多少步使 N 变成 M
思路:
判断素数的话直接利用埃筛就可以了,因为只能改变一位数所以我们每次去找和当前这个数只有一位数不同的素数就可以了!
具体的代码:
1 #include <iostream> 2 #include <string> 3 #include <cstring> 4 #include <queue> 5 #include <stdio.h> 6 7 using namespace std; 8 9 const int N = 10010; 10 typedef struct Node{ 11 int val; 12 int cnt; 13 }Node; 14 15 int T; 16 int a[N],prime[N],vis[N]; 17 int tot,p; 18 int n = 10000; 19 int m; 20 21 bool one_digit(int l,int r) // 判断是否只有一位数不同 22 { 23 int sum = 0; 24 int temp1,temp2; 25 while (l!=0) 26 { 27 temp1 = l%10; 28 temp2 = r%10; 29 if (temp1!=temp2) 30 sum++; 31 l /= 10; 32 r /= 10; 33 } 34 if (sum==1) 35 return true; 36 return false; 37 } 38 39 40 41 int bfs() 42 { 43 queue<Node> q; 44 Node node; 45 // memset(vis,0, sizeof(vis)); 46 node.val = n; 47 node.cnt = 0; 48 q.push(node); 49 vis[node.val] = 1; 50 while (!q.empty()) 51 { 52 Node cur = q.front(); 53 q.pop(); 54 if (cur.val == m) 55 return cur.cnt; 56 for (int i=p-1;i>=0;i--) 57 { 58 Node next = cur; 59 if (!vis[prime[i]] && one_digit(next.val,prime[i])) 60 { 61 vis[prime[i]] = 1; 62 next.val = prime[i]; 63 next.cnt++; 64 q.push(next); 65 } 66 } 67 } 68 return -1; 69 } 70 71 72 int main() 73 { 74 // 埃筛 75 for (int i=2;i<=n;i++) 76 { 77 if (!vis[i]) 78 { 79 a[tot++] = i; 80 for (int j=2*i;j<=n;j+=i) 81 vis[j] = 1; 82 } 83 } 84 for (int i=0;i<tot;i++) 85 { 86 if (a[i]>1000) 87 prime[p++] = a[i]; 88 } 89 cin >> T; 90 while (T--) 91 { 92 cin >> n >> m; 93 memset(vis,0, sizeof(vis)); 94 int ant = bfs(); 95 if (ant<0) 96 { 97 printf("Impossible "); 98 } 99 else 100 printf("%d ",ant); 101 } 102 }