poj3126--Prime Path(广搜)
Prime Path
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 11751 | Accepted: 6673 |
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.
— 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.
1733
3733
3739
3779
8779
8179
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
给出两个数s,e,都是素数。经过转化,将s转化为e的最小步数
规则,每一次仅仅能改动一位,每次得到的数都是素数。
素数筛跑出1000到10000内的全部素数。假设当中两个素数仅仅有一位不同。那么连接一条边。得到全部素数组合的图后用bfs直接搜索就能够
#include <cstdio> #include <cstring> #include <queue> #include <algorithm> using namespace std; int a[11000] , check[11000] , tot ; struct node{ int v , next ; }p[2000000]; struct node1{ int u , t ; }; queue <node1> que ; int head[10000] , cnt , flag[10000] ; void add(int u,int v) { p[cnt].v = v ; p[cnt].next = head[u] ; head[u] = cnt++ ; } void init() { memset(check,0,sizeof(check)); memset(head,-1,sizeof(head)); tot = cnt = 0 ; int i , j , k , num ; for(i = 2 ; i <= 10000 ; i++) { if( !check[i] ) a[tot++] = i ; for(j = 0 ; j < tot ; j++) { if(i*a[j] >= 10000) break; check[i*a[j]] = 1 ; if( i%a[j] == 0 ) break; } } for(i = 0 ; i < tot ; i++) if( (a[i]/1000) ) break; k = i ; for(i = k ; i < tot ; i++) { for(j = k ; j < i ; j++) { num = 0 ; if( a[i]%10 != a[j]%10 ) num++ ; if( a[i]/10%10 != a[j]/10%10 ) num++ ; if( a[i]/100%10 != a[j]/100%10 ) num++ ; if( a[i]/1000%10 != a[j]/1000%10 ) num++ ; if(num == 1) { add(i,j); add(j,i); } } } } int find1(int x) { int low = 0 , mid , high = tot-1 ; while(low <= high) { mid = (low+high)/2 ; if(a[mid] == x) return mid ; else if(a[mid] < x) low = mid + 1 ; else high = mid -1 ; } } int bfs(int s,int e) { memset(flag,0,sizeof(flag)); while( !que.empty() ) que.pop(); int i , j , v ; node1 low , high ; low.u = s ; low.t = 0 ; flag[s] = 1 ; que.push(low); while( !que.empty() ) { low = que.front(); que.pop(); if( low.u == e ) return low.t ; for(i = head[low.u] ; i != -1 ; i = p[i].next) { v = p[i].v ; if( !flag[v] ) { flag[v] = 1; high.u = v ; high.t = low.t + 1 ; que.push(high); } } } return 0; } int main() { int t , s , e ; init(); scanf("%d", &t); while(t--) { scanf("%d %d", &s, &e); s = find1(s); e = find1(e); printf("%d\n", bfs(s,e) ); } return 0; }