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\n",ans);
143         else
144         printf("Impossible\n");
145     }
146     return 0;
147 }

 



posted @ 2016-11-06 00:16  抓不住Jerry的Tom  阅读(231)  评论(0编辑  收藏  举报