zoukankan      html  css  js  c++  java
  • POJ 3126 Prime Path (bfs+欧拉线性素数筛)

    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

    题意给你两个4位素数a b,让你将a每次改变一位数字,改变后的4位数还必须是素数,最少几步能变到b,输出步数,不能变到输出Impossible。
    这题第一发T了...一看就是果然T,忘了加vis2这个数组标记那些数组被访问过了...不加的话因为队列及时pop了,会出现在两个素数之间来回跳的情况!
    小插曲就是欧拉线性素数筛,自己还没背会2333333。
    代码如下:
      1 #include <iostream>
      2 #include <cstdio>
      3 #include <queue>
      4 #include <algorithm>
      5 #include <cstring>
      6 using namespace std;
      7 #define inf 0x3f3f3f3f
      8 int prime[11000],a,b,ans;
      9 bool num[11000],vis[11000],vis2[11000];
     10 bool flag;
     11 int dig[4];
     12 struct node
     13 {
     14     int x,stp;
     15 };
     16 void split (int x)//将x分成各个位
     17 {
     18     for (int i=0;i<4;++i)
     19     {
     20         dig[i]=x%10;
     21         x/=10;
     22     }
     23 }
     24 int getnum (int a,int b,int c,int d)//将4个数字组成一个四位数
     25 {
     26     return a+b*10+c*100+d*1000;
     27 }
     28 void getprime()//欧拉线性素数筛
     29 {
     30     memset(num,false,sizeof num);
     31     memset(vis,false,sizeof vis);
     32     memset(prime,0,sizeof prime);
     33     int cnt=0;
     34     for (int i=2;i<11000;++i)
     35     {
     36         if (!vis[i])
     37         prime[cnt++]=i,num[i]=1;
     38         for (int j=0;j<cnt&&i*prime[j]<11000;++j)
     39         {
     40             vis[i*prime[j]]=1;
     41             if (i%prime[j]==0)
     42             break;
     43         }
     44     }
     45 }
     46 void bfs(node now)
     47 {
     48     queue<node>q;
     49     q.push(now);
     50     vis2[now.x]=true;
     51     if (now.x==b)
     52     {
     53         flag=true;
     54         ans=now.stp;
     55         return ;
     56     }
     57     while (!q.empty())
     58     {
     59         node frt=q.front();
     60         q.pop();
     61         if (frt.x==b)
     62         {
     63             flag=true;
     64             ans=frt.stp;
     65             return ;
     66         }
     67         split(frt.x);
     68         for (int i=0;i<=9;++i)//改个位
     69         {
     70             int temp=getnum(i,dig[1],dig[2],dig[3]);
     71             if (temp==frt.x)
     72             continue;
     73             if (num[temp]&&!vis2[temp])
     74             {
     75                 node tp;
     76                 tp.x=temp;
     77                 tp.stp=frt.stp+1;
     78                 vis2[temp]=true;
     79                 q.push(tp);
     80             }
     81         }
     82         for (int i=0;i<=9;++i)//改十位
     83         {
     84             int temp=getnum(dig[0],i,dig[2],dig[3]);
     85             if (temp==frt.x)
     86             continue;
     87             if (num[temp]&&!vis2[temp])
     88             {
     89                 node tp;
     90                 tp.x=temp;
     91                 tp.stp=frt.stp+1;
     92                 vis2[temp]=true;
     93                 q.push(tp);
     94             }
     95         }
     96         for (int i=0;i<=9;++i)//改百位
     97         {
     98             int temp=getnum(dig[0],dig[1],i,dig[3]);
     99             if (temp==frt.x)
    100             continue;
    101             if (num[temp]&&!vis2[temp])
    102             {
    103                 node tp;
    104                 tp.x=temp;
    105                 tp.stp=frt.stp+1;
    106                 vis2[temp]=true;
    107                 q.push(tp);
    108             }
    109         }
    110         for (int i=1;i<=9;++i)//改千位,注意是4位数,所以千位不为0,从一开始
    111         {
    112             int temp=getnum(dig[0],dig[1],dig[2],i);
    113             if (temp==frt.x)
    114             continue;
    115             if (num[temp]&&!vis2[temp])
    116             {
    117                 node tp;
    118                 tp.x=temp;
    119                 tp.stp=frt.stp+1;
    120                 vis2[temp]=true;
    121                 q.push(tp);
    122             }
    123         }
    124     }
    125     return ;
    126 }
    127 int main()
    128 {
    129     getprime();
    130     //freopen("de.txt","r",stdin);
    131     int t;
    132     scanf("%d",&t);
    133     while (t--)
    134     {
    135         scanf("%d%d",&a,&b);
    136         memset(vis2,false,sizeof vis2);
    137         ans=inf;
    138         node now;
    139         now.x=a,now.stp=0;
    140         bfs(now);
    141         if (flag)
    142         printf("%d
    ",ans);
    143         else
    144         printf("Impossible
    ");
    145     }
    146     return 0;
    147 }


  • 相关阅读:
    德国闪电战和苏联大纵深,谁更厉害?(一个是为了避免战略上的持久战,一个是为了战役的突破)
    “MEAN”技术栈开发web应用
    MVC 01
    适配器模式
    w3wp占用CPU过高
    安装tensorflow
    MemCache分布式内存对象缓存系统
    MVC 使用IBatis.net
    分布式计算
    Remote Desktop Connection Manager
  • 原文地址:https://www.cnblogs.com/agenthtb/p/6034484.html
Copyright © 2011-2022 走看看