题目链接:http://poj.org/problem?id=3126
Prime Path
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 22936 | Accepted: 12706 |
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
Source
题解:
1.打印素数表。
2.由于只有四位数,直接枚举不会超时。由于要求的是“最少步数”,所以用BFS进行搜索。
写法一:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <vector> 7 #include <queue> 8 #include <stack> 9 #include <map> 10 #include <string> 11 #include <set> 12 #define ms(a,b) memset((a),(b),sizeof((a))) 13 using namespace std; 14 typedef long long LL; 15 const int INF = 2e9; 16 const LL LNF = 9e18; 17 const int MOD = 1e9+7; 18 const int MAXN = 5+10; 19 20 struct node //num为素数,dig[]为这个素数的每个位上的数,便于操作。 21 { 22 int num, dig[4], step; 23 }; 24 25 int vis[100010], pri[100010]; 26 27 queue<node>que; 28 int bfs(node s, node e) 29 { 30 ms(vis,0); 31 while(!que.empty()) que.pop(); 32 s.step = 0; 33 vis[s.num] = 1; 34 que.push(s); 35 36 node now, tmp; 37 while(!que.empty()) 38 { 39 now = que.front(); 40 que.pop(); 41 42 if(now.num==e.num) 43 return now.step; 44 45 for(int i = 0; i<4; i++) //枚举位数 46 for(int j = 0; j<10; j++) //枚举数字 47 { 48 if(i==3 && j==0) continue; //首位不能为0 49 tmp = now; 50 tmp.dig[i] = j; //第i为变为j 51 tmp.num = tmp.dig[0] + tmp.dig[1]*10+tmp.dig[2]*100+tmp.dig[3]*1000; 52 if(!pri[tmp.num] && !vis[tmp.num]) //num为素数并且没有被访问 53 { 54 vis[tmp.num] = 1; 55 tmp.step++; 56 que.push(tmp); 57 } 58 } 59 } 60 return -1; 61 } 62 63 void init() //素数表,pri[]==0的为素数 64 { 65 int m = sqrt(100000+0.5); 66 ms(pri,0); 67 pri[1] = 1; 68 for(int i = 2; i<=m; i++) if(!pri[i]) 69 for(int j = i*i; j<=100000; j += i) 70 pri[j] = 1; 71 } 72 73 int main() 74 { 75 init(); 76 int T; 77 scanf("%d",&T); 78 while(T--) 79 { 80 int n, m; 81 node s, e; 82 scanf("%d%d",&n,&m); 83 s.num = n; e.num = m; 84 for(int i = 0; i<4; i++, n /= 10) s.dig[i] = n%10; 85 for(int i = 0; i<4; i++, m /= 10) e.dig[i] = m%10; 86 87 int ans = bfs(s,e); 88 if(ans==-1) 89 puts("Impossible"); 90 else 91 printf("%d ",ans); 92 } 93 }
写法二:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <vector> 7 #include <queue> 8 #include <stack> 9 #include <map> 10 #include <string> 11 #include <set> 12 #define ms(a,b) memset((a),(b),sizeof((a))) 13 using namespace std; 14 typedef long long LL; 15 const int INF = 2e9; 16 const LL LNF = 9e18; 17 const int MOD = 1e9+7; 18 const int MAXN = 5+10; 19 20 struct node 21 { 22 int num, step; 23 }; 24 25 int vis[100010], dig[5]; 26 int pri[100010]; 27 28 queue<node>que; 29 int bfs(int s, int e) 30 { 31 ms(vis,0); 32 while(!que.empty()) que.pop(); 33 34 node now, tmp; 35 now.num = s; 36 now.step = 0; 37 vis[now.num] = 1; 38 que.push(now); 39 40 while(!que.empty()) 41 { 42 now = que.front(); 43 que.pop(); 44 45 if(now.num==e) 46 return now.step; 47 48 dig[0] = now.num%10; 49 dig[1] = (now.num/10)%10; 50 dig[2] = (now.num/100)%10; 51 dig[3] = (now.num/1000)%10; 52 for(int i = 0; i<4; i++) 53 for(int j = 0; j<10; j++) 54 { 55 if(i==3 && j==0) continue; 56 tmp.num = now.num + (j- dig[i])*pow(10,i); //pow前面不要加上强制类型(int) 57 // tmp.num = now.num + (j- dig[i])* (int)pow(10,i); 58 // (int)pow(10,2) 居然等于99, 看来还是不要依赖这些函数 59 if(!pri[tmp.num] && !vis[tmp.num]) 60 { 61 vis[tmp.num] = 1; 62 tmp.step = now.step + 1; 63 que.push(tmp); 64 } 65 } 66 } 67 return -1; 68 } 69 70 void init() 71 { 72 int m = sqrt(100000+0.5); 73 ms(pri,0); 74 pri[1] = 1; 75 for(int i = 2; i<=m; i++) if(!pri[i]) 76 for(int j = i*i; j<=100000; j += i) 77 pri[j] = 1; 78 } 79 80 int main() 81 { 82 init(); 83 int T; 84 scanf("%d",&T); 85 while(T--) 86 { 87 int n, m; 88 scanf("%d%d",&n,&m); 89 int ans = bfs(n,m); 90 if(ans==-1) 91 puts("Impossible"); 92 else 93 printf("%d ",ans); 94 } 95 }