Prime Path
Time Limit: 1000MS |
|
Memory Limit: 65536K |
Total Submissions: 15364 |
|
Accepted: 8658 |
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
7
0
^0^自己想出来了,好高兴啊。自己做的和看别人题解做出来的感觉就是不一样。
题目大意:
给两个个千位数的数字,千位不能为0。每次只能转变千位数的一个数字,且每次变换前后该数字都是素数,问,从从第一个千位数变成第二个千位数所需要的最小的数字变换的次数。
遇到的问题和思路:
首先,预处理,用埃氏筛法将1000-9999的所有素数都枚举和标记出来。然后用队列,因为1000-10000中的素数个数有1061个,所以复杂度最多也就O(1000 * 每一个数字),然后就是将一个数字从个位十位百位千位一个一个枚举,一共就9 * 4 = 36 就约等于50步。所以复杂度为O(1000 * 50)符合要求。
//预处理判断素数 #include<cstdio> #include<algorithm> #include<cstring> #include<queue> #include<cmath> using namespace std; bool prim[10000 + 5]; int map[10000 + 5]; int n, m; queue <int> que; void cal(int fi){ //分别走完个位十位百位千位 int tmp = fi - fi % 10; for (int i = 0; i <= 9; i++){ if (map[tmp] == 0 && prim[tmp]){ que.push(tmp); map[tmp] = map[fi] + 1; } if (tmp == m){ while(!que.empty()) que.pop(); que.push(tmp); return ; } tmp++; } tmp = fi - (fi % 100 / 10) * 10; for (int i = 0; i <= 9; i++){ if (map[tmp] == 0 && prim[tmp]){ que.push(tmp); map[tmp] = map[fi] + 1; } if (tmp == m){ while(!que.empty()) que.pop(); que.push(tmp); return ; } tmp += 10; } tmp = fi - (fi / 100 % 10) * 100; for (int i = 0; i <= 9; i++){ if (map[tmp] == 0 && prim[tmp]){ que.push(tmp); map[tmp] = map[fi] + 1; } if (tmp == m){ while(!que.empty()) que.pop(); que.push(tmp); return ; } tmp += 100; } tmp = (fi % 1000) + 1000; for (int i = 1; i <= 9; i++){ if (map[tmp] == 0 && prim[tmp]){ que.push(tmp); map[tmp] = map[fi] + 1; } if (tmp == m){ while(!que.empty()) que.pop(); que.push(tmp); return ; } tmp += 1000; } } void dfs(int n){ que.push(n); int fi; while (!que.empty()){ fi = que.front(); que.pop(); if (fi == m){ break; } cal(fi); } printf("%d\n", map[fi] - 1); } void solve(){ memset(map, 0, sizeof(map)); scanf("%d%d", &n, &m); if (!prim[n] || !prim[m]){ printf("Impossible\n"); return ; } map[n] = 1;//刚开始赋值 dfs (n); while (!que.empty()) que.pop(); } void init(){ for (int i = 2; i <= 9999; i++){ prim[i] = true; } for (int i = 2; i <= 100; i++){ if (prim[i]){ for (int j = 2 * i; j <= 9999; j += i) prim[j] = false; } } } int main(){ init(); int T; scanf("%d", &T); while (T--){ solve(); } return 0; } </int></cmath></queue></cstring></algorithm></cstdio>