POJ-3126.PrimePath(欧拉筛素数打表 + BFS)

 

给出一篇有关素数线性筛和区间筛的博客,有兴趣的读者可以自取。

  

  本题大意:

    给定两个四位的素数,没有前导零,每次变换其中的一位,最终使得两个素数相等,输出最小变换次数。要求变换过程中的数也都是素数。

  本题思路:

    求最小步数,用BFS,判断素数,用欧拉筛打表。

  参考代码:

 1 #include <cstdio>
 2 #include <queue>
 3 #include <map>
 4 #include <cstring>
 5 using namespace std;
 6 
 7 
 8 int star, finish, ans, total = 0;
 9 const int maxn = 10000 + 5;
10 bool isprime[maxn];
11 bool isvisited[maxn];
12 int prime[1300];
13 
14 struct node{
15     int cur, step;
16 } now, Next;
17 
18 void get_prime() {//欧拉筛打表
19     memset(isprime, false, sizeof(isprime));
20     for(int i  = 2; i < maxn; i ++) {
21         if(!isprime[i])
22             prime[total ++] = i;
23         for(int j = 0; j < total; j ++) {
24             if(prime[j] * i > maxn) break;
25             isprime[prime[j] * i] = true;
26             if(i % prime[j] == 0)   break;
27         }
28     }
29 }
30 
31 int bfs() {
32     queue <node> Q;
33     isvisited[star] = true;
34     now.cur = star;
35     now.step = 0;
36     Q.push(now);
37     while(!Q.empty()) {
38         char num[5];
39         now = Q.front();
40         Q.pop();
41         if(now.cur == finish)    return now.step;
42         for(int i = 0; i < 4; i ++) {
43             sprintf(num, "%d", now.cur);
44             for(int j = 0; j < 10; j ++) {
45                 if(j == 0 && i == 0)    continue;
46                 if(i == 0)
47                     Next.cur = j * 1000 + (num[1] - '0') * 100 + (num[2] - '0') * 10 + (num[3] - '0');
48                 else if(i == 1)
49                     Next.cur = j * 100 + (num[0] - '0') * 1000 +(num[2] - '0') * 10 + (num[3] - '0');
50                 else if(i == 2)
51                     Next.cur = j * 10 + (num[0] - '0') * 1000 + (num[1] - '0') * 100 + (num[3] - '0');
52                 else if(i == 3)
53                     Next.cur = j + (num[0] - '0') * 1000 + (num[1] - '0') * 100 + (num[2] - '0') * 10;   
54                 if(!isprime[Next.cur] && !isvisited[Next.cur]) {
55                     Next.step = now.step + 1;
56                     isvisited[Next.cur] = 1;
57                     Q.push(Next);
58                 }
59             }
60         }
61     }
62     return -1;
63 }
64 
65 int main () {
66     memset(isvisited, false, sizeof(isvisited));
67     get_prime();
68     int t;
69     scanf("%d", &t);
70     while(t --) {
71         memset(isvisited, false, sizeof(isvisited));
72         scanf("%d %d", &star, &finish);
73         ans = bfs();
74         if(ans == -1)   printf("Impossible\n");
75         else    printf("%d\n", ans);
76     }
77     return 0;
78 }
View Code

 

posted @ 2019-03-05 21:23  Cruel_King  阅读(221)  评论(0编辑  收藏  举报