POJ-3126 Prime Path

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

大致题意:多组样例,给定两个四位质数,作为起点和终点,要求每次改变一位数字,改变后的数字仍为质数,输出最少的改变步数

可以先把所有的质数先筛选出来,之后bfs,每次改变一位数字并判断其是否为质数,直至到达终点,代码如下:
 1 #include<stdio.h>
 2 #include<iostream>
 3 #include<string.h>
 4 #include<algorithm>
 5 #include<queue>
 6 using namespace std;
 7 void read(int &x)
 8 {
 9     int f=0;x=0;char s=getchar();
10     while(s>'9'||s<'0'){if(s=='-')f=1;s=getchar();}
11     while(s>='0'&&s<='9'){x=(x<<1)+(x<<3)+(s^48);s=getchar();}
12     x=f?-x:x;
13 }
14 int t,x,y,cnt=0,prime[10005],a,b,c,d,ans;
15 bool num[10005],vis[10005];
16 struct node{
17     int k,cost;
18 };
19 int bfs()
20 {
21     queue<node>q;
22     node now,next;
23     now.k=x,now.cost=0,vis[now.k]=1;
24     q.push(now);
25     while(!q.empty())
26     {
27         now=q.front();
28         q.pop();
29         if(now.k==y) return now.cost;
30         a=now.k/1000,b=now.k/100%10,c=now.k/10%10,d=now.k%10;
31         for(int i=1;i<=9;++i)
32         {
33             if(i==a) continue;
34             next.k=i*1000+b*100+c*10+d;
35             if(vis[next.k]||num[next.k]==0) continue;
36             next.cost=now.cost+1,vis[next.k]=1;
37             q.push(next);
38         }
39         for(int i=0;i<=9;++i)
40         {
41             if(i==b) continue;
42             next.k=a*1000+i*100+c*10+d;
43             if(vis[next.k]||num[next.k]==0) continue;
44             next.cost=now.cost+1,vis[next.k]=1;
45             q.push(next);
46         }
47         for(int i=0;i<=9;++i)
48         {
49             if(i==c) continue;
50             next.k=a*1000+b*100+i*10+d;
51             if(vis[next.k]||num[next.k]==0) continue;
52             next.cost=now.cost+1,vis[next.k]=1;
53             q.push(next);
54         }
55         for(int i=0;i<=9;++i)
56         {
57             if(i==d) continue;
58             next.k=a*1000+b*100+c*10+i;
59             if(vis[next.k]||num[next.k]==0) continue;
60             next.cost=now.cost+1,vis[next.k]=1;
61             q.push(next);
62         }
63     }
64     return 0;
65 }
66 int main()
67 {
68     memset(num,1,sizeof(num));
69     num[0]=num[1]=0;
70     for(int i=2;i<=10000;++i)
71     {
72         if(num[i]) prime[++cnt]=i;
73         for(int j=1;j<=cnt&&prime[j]*i<=10000;++j)
74         {
75             num[prime[j]*i]=0;
76             if(!(i%prime[j])) break;
77         }
78     }
79     read(t);
80     while(t--)
81     {
82         memset(vis,0,sizeof(vis));
83         read(x),read(y);
84         if(x==y)
85         {
86             printf("0\n");
87             continue;
88         }
89         ans=bfs();
90         if(ans) printf("%d\n",ans);
91         else printf("Impossible\n");
92     }
93     return 0;
94 }

猜你喜欢

转载自www.cnblogs.com/n0-b0dy/p/9382706.html