zoukankan      html  css  js  c++  java
  • POJ3126 Prime Path —— BFS + 素数表

    题目链接:http://poj.org/problem?id=3126


    Prime Path
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 22936   Accepted: 12706

    Description

    The ministers of the cabinet were quite upset by the message from the Chief of Security stating that they would all have to change the four-digit room numbers on their offices. 
    — It is a matter of security to change such things every now and then, to keep the enemy in the dark. 
    — But look, I have chosen my number 1033 for good reasons. I am the Prime minister, you know! 
    — I know, so therefore your new number 8179 is also a prime. You will just have to paste four new digits over the four old ones on your office door. 
    — No, it’s not that simple. Suppose that I change the first digit to an 8, then the number will read 8033 which is not a prime! 
    — I see, being the prime minister you cannot stand having a non-prime number on your door even for a few seconds. 
    — Correct! So I must invent a scheme for going from 1033 to 8179 by a path of prime numbers where only one digit is changed from one prime to the next prime.

    Now, the minister of finance, who had been eavesdropping, intervened. 
    — No unnecessary expenditure, please! I happen to know that the price of a digit is one pound. 
    — Hmm, in that case I need a computer program to minimize the cost. You don't know some very cheap software gurus, do you? 
    — In fact, I do. You see, there is this programming contest going on... Help the prime minister to find the cheapest prime path between any two given four-digit primes! The first digit must be nonzero, of course. Here is a solution in the case above. 
    1033
    1733
    3733
    3739
    3779
    8779
    8179
    The cost of this solution is 6 pounds. Note that the digit 1 which got pasted over in step 2 can not be reused in the last step – a new 1 must be purchased.

    Input

    One line with a positive number: the number of test cases (at most 100). Then for each test case, one line with two numbers separated by a blank. Both numbers are four-digit primes (without leading zeros).

    Output

    One line for each case, either with a number stating the minimal cost or containing the word Impossible.

    Sample Input

    3
    1033 8179
    1373 8017
    1033 1033

    Sample Output

    6
    7
    0

    Source



    题解:

    1.打印素数表。

    2.由于只有四位数,直接枚举不会超时。由于要求的是“最少步数”,所以用BFS进行搜索。




    写法一:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <algorithm>
     6 #include <vector>
     7 #include <queue>
     8 #include <stack>
     9 #include <map>
    10 #include <string>
    11 #include <set>
    12 #define ms(a,b) memset((a),(b),sizeof((a)))
    13 using namespace std;
    14 typedef long long LL;
    15 const int INF = 2e9;
    16 const LL LNF = 9e18;
    17 const int MOD = 1e9+7;
    18 const int MAXN = 5+10;
    19 
    20 struct node //num为素数,dig[]为这个素数的每个位上的数,便于操作。
    21 {
    22     int num, dig[4], step;
    23 };
    24 
    25 int vis[100010], pri[100010];
    26 
    27 queue<node>que;
    28 int bfs(node s, node e)
    29 {
    30     ms(vis,0);
    31     while(!que.empty()) que.pop();
    32     s.step = 0;
    33     vis[s.num] = 1;
    34     que.push(s);
    35 
    36     node now, tmp;
    37     while(!que.empty())
    38     {
    39         now = que.front();
    40         que.pop();
    41 
    42         if(now.num==e.num)
    43             return now.step;
    44 
    45         for(int i = 0; i<4; i++)    //枚举位数
    46         for(int j = 0; j<10; j++)   //枚举数字
    47         {
    48             if(i==3 && j==0) continue;  //首位不能为0
    49             tmp = now;
    50             tmp.dig[i] = j;     //第i为变为j
    51             tmp.num = tmp.dig[0] + tmp.dig[1]*10+tmp.dig[2]*100+tmp.dig[3]*1000;
    52             if(!pri[tmp.num] && !vis[tmp.num])  //num为素数并且没有被访问
    53             {
    54                 vis[tmp.num] = 1;
    55                 tmp.step++;
    56                 que.push(tmp);
    57             }
    58         }
    59     }
    60     return -1;
    61 }
    62 
    63 void init()     //素数表,pri[]==0的为素数
    64 {
    65     int m = sqrt(100000+0.5);
    66     ms(pri,0);
    67     pri[1] = 1;
    68     for(int i = 2; i<=m; i++) if(!pri[i])
    69         for(int j = i*i; j<=100000; j += i)
    70             pri[j] = 1;
    71 }
    72 
    73 int main()
    74 {
    75     init();
    76     int T;
    77     scanf("%d",&T);
    78     while(T--)
    79     {
    80         int n, m;
    81         node s, e;
    82         scanf("%d%d",&n,&m);
    83         s.num = n; e.num = m;
    84         for(int i = 0; i<4; i++, n /= 10) s.dig[i] = n%10;
    85         for(int i = 0; i<4; i++, m /= 10) e.dig[i] = m%10;
    86 
    87         int ans = bfs(s,e);
    88         if(ans==-1)
    89             puts("Impossible");
    90         else
    91             printf("%d
    ",ans);
    92     }
    93 }
    View Code


    写法二:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <algorithm>
     6 #include <vector>
     7 #include <queue>
     8 #include <stack>
     9 #include <map>
    10 #include <string>
    11 #include <set>
    12 #define ms(a,b) memset((a),(b),sizeof((a)))
    13 using namespace std;
    14 typedef long long LL;
    15 const int INF = 2e9;
    16 const LL LNF = 9e18;
    17 const int MOD = 1e9+7;
    18 const int MAXN = 5+10;
    19 
    20 struct node
    21 {
    22     int num, step;
    23 };
    24 
    25 int vis[100010], dig[5];
    26 int pri[100010];
    27 
    28 queue<node>que;
    29 int bfs(int s, int e)
    30 {
    31     ms(vis,0);
    32     while(!que.empty()) que.pop();
    33 
    34     node now, tmp;
    35     now.num = s;
    36     now.step = 0;
    37     vis[now.num] = 1;
    38     que.push(now);
    39 
    40     while(!que.empty())
    41     {
    42         now = que.front();
    43         que.pop();
    44 
    45         if(now.num==e)
    46             return now.step;
    47 
    48         dig[0] = now.num%10;
    49         dig[1] = (now.num/10)%10;
    50         dig[2] = (now.num/100)%10;
    51         dig[3] = (now.num/1000)%10;
    52         for(int i = 0; i<4; i++)
    53         for(int j = 0; j<10; j++)
    54         {
    55             if(i==3 && j==0) continue;
    56             tmp.num = now.num + (j- dig[i])*pow(10,i);  //pow前面不要加上强制类型(int)
    57 //            tmp.num = now.num + (j- dig[i])* (int)pow(10,i);
    58 //            (int)pow(10,2) 居然等于99, 看来还是不要依赖这些函数
    59             if(!pri[tmp.num] && !vis[tmp.num])
    60             {
    61                 vis[tmp.num] = 1;
    62                 tmp.step = now.step + 1;
    63                 que.push(tmp);
    64             }
    65         }
    66     }
    67     return -1;
    68 }
    69 
    70 void init()
    71 {
    72     int m = sqrt(100000+0.5);
    73     ms(pri,0);
    74     pri[1] = 1;
    75     for(int i = 2; i<=m; i++) if(!pri[i])
    76         for(int j = i*i; j<=100000; j += i)
    77             pri[j] = 1;
    78 }
    79 
    80 int main()
    81 {
    82     init();
    83     int T;
    84     scanf("%d",&T);
    85     while(T--)
    86     {
    87         int n, m;
    88         scanf("%d%d",&n,&m);
    89         int ans = bfs(n,m);
    90         if(ans==-1)
    91             puts("Impossible");
    92         else
    93             printf("%d
    ",ans);
    94     }
    95 }
    View Code
  • 相关阅读:
    排序算法的稳定性
    字符串处理常用函数
    判断两棵二叉树是否相等
    约瑟夫环
    自加++
    Linux 安装配置 Tomcat
    在 eclipse 中将 web 项目部署到 tomcat 服务器上
    PHP连接MySQL数据库
    logback
    Log4J
  • 原文地址:https://www.cnblogs.com/DOLFAMINGO/p/7538594.html
Copyright © 2011-2022 走看看