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 70 题意给你两个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 }