双向广搜 POJ 3126 Prime Path
POJ 3126 Prime Path
Description ![]() — 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. 1033The 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 大致题意: 给定两个四位素数a b,要求把a变换到b 变换的过程要保证 每次变换出来的数都是一个 四位素数,而且当前这步的变换所得的素数 与 前一步得到的素数 只能有一个位不同,而且每步得到的素数都不能重复。 求从a到b最少需要的变换次数。无法变换则输出Impossible
注意:双向广搜是在一个队列中实现的,只不过是交替进行罢了! |
1 #include<iostream> 2 using namespace std; 3 #include<cstdio> 4 #include<cstring> 5 #include<cmath> 6 #include<cstdlib> 7 #include<queue> 8 #define N 10000 9 struct prime{ 10 int c[4]; 11 int flag; 12 }; 13 int dis[N]; 14 int visit[N]; 15 queue<prime>que; 16 int js(int *m) 17 { 18 return (m[0]*1000+m[1]*100+m[2]*10+m[3]*1); 19 } 20 bool is_prime(int l) 21 { 22 bool flag=true; 23 for(int i=2;i<=sqrt(l);++i) 24 { 25 if(l%i==0) 26 { 27 flag=false; 28 break; 29 } 30 } 31 return flag; 32 } 33 int bfs() 34 { 35 while(!que.empty()) 36 { 37 prime x=que.front(); 38 que.pop(); 39 int now=js(x.c); 40 for(int i=1;i<=9;++i) 41 { 42 prime nx=x; 43 nx.c[0]=i; 44 int shu=js(nx.c); 45 if(!visit[shu]&&is_prime(shu)) 46 { 47 visit[shu]=x.flag; 48 nx.flag=x.flag; 49 que.push(nx); 50 dis[shu]=dis[now]+1; 51 } 52 else if(visit[shu]&&visit[shu]!=x.flag) 53 { 54 return dis[now]+dis[shu]+1; 55 } 56 } 57 for(int j=1;j<=3;++j) 58 { 59 for(int i=0;i<=9;++i) 60 { 61 prime nx=x; 62 nx.c[j]=i; 63 int shu=js(nx.c); 64 if(!visit[shu]&&is_prime(shu)) 65 { 66 visit[shu]=x.flag; 67 nx.flag=x.flag; 68 que.push(nx); 69 dis[shu]=dis[now]+1; 70 } 71 else if(visit[shu]&&visit[shu]!=x.flag) 72 { 73 return dis[now]+dis[shu]+1; 74 } 75 } 76 77 } 78 } 79 return -1; 80 } 81 int main() 82 { 83 int tex; 84 scanf("%d",&tex); 85 char a[10]; 86 while(tex--) 87 { 88 while(!que.empty()) que.pop(); 89 memset(dis,0,sizeof(dis)); 90 memset(visit,0,sizeof(visit)); 91 scanf("%s",a); 92 que.push(prime{a[0]-'0',a[1]-'0',a[2]-'0',a[3]-'0',1}); 93 int p=(a[0]-'0')*1000+(a[1]-'0')*100+(a[2]-'0')*10+(a[3]-'0'); 94 visit[p]=1;dis[p]=0; 95 int q=p; 96 scanf("%s",a); 97 que.push(prime{a[0]-'0',a[1]-'0',a[2]-'0',a[3]-'0',2}); 98 p=(a[0]-'0')*1000+(a[1]-'0')*100+(a[2]-'0')*10+(a[3]-'0'); 99 visit[p]=2;dis[p]=0; 100 if(q==p) 101 { 102 printf("0\n");continue; 103 } 104 int temp=bfs(); 105 if(temp==-1) printf("Impossible\n"); 106 else printf("%d\n",temp); 107 } 108 return 0; 109 }