您的位置:首页 > 其它

POJ3126(素数表+广搜BFS)

2016-07-08 16:36 661 查看
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

题意:给你一个素数,让你把它变为另一个素数,每一次只能改变一位,而且每改变一位后所得的需要是素数。每一次改变都会花费1英镑,问你最少花费多少英镑能转化过去。

题解:由于是素数问题,先用埃式筛法筛出1-9999的所有素数。然后再依次枚举每一位,把每一次通过一个数枚举出的素数当作一层。知道枚举出的数和所需结果相同。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <map>
#include <queue>
#include <cmath>
#include <vector>

using namespace std;

const int maxn = 10000 + 5;
bool is_prime[maxn] = {0};
bool vis[maxn];
int cost[maxn];

void sieve() { // 埃式筛法筛素数
memset(is_prime, true, sizeof(is_prime));
is_prime[0] = is_prime[1] = false;
int n=9999;
for(int i=2; i<=n; ++i)
if(is_prime[i])
for(int j=2*i; j<=n; j+=i) is_prime[j] = false;
return;
}

int canbenext(int a, int w, int num)
{
int b, c, a1;
if (w == 1) {
a = a / 10 * 10 + num;
} else if (w == 2) {
a = a / 100 * 100 + a % 10 + num * 10;
} else if (w == 3) {
a = a / 1000 * 1000 + a % 100 + num * 100;
} else if (w == 4) {
a = a % 1000 + num * 1000;
}
if (is_prime[a]) return a;
else return 0;
}

void BFS(int a, int b)
{
memset (vis, false, sizeof(vis));
memset (cost, 0, sizeof(cost));
queue<int> q;
q.push (a);
vis[a] = 1;
cost[a] = 0;
while (!q.empty()) {
int c = q.front(); q.pop();
if (c == b) {
printf ("%d\n", cost[c]);
return;
}
//枚举可以转化成的数
for (int i = 1; i <= 4; i++) {
for (int j = 0; j <= 9; j++) {
if ((i == 1 && j % 2 == 0) || (i == 4 && j == 0)) continue;
int d = canbenext (c, i, j);
if (d && !vis[d]) {
vis[d] = 1;
q.push(d);
cost[d] = cost[c] + 1;
}
}
}
}
}

int main()
{
#ifndef ONLINE_JUDGE
freopen ("in.txt", "r", stdin);
#endif // ONLINE_JUDGE
sieve ();
int t;
scanf ("%d", &t);
while (t--) {
int a, b;
scanf ("%d%d", &a, &b);
BFS (a, b);
//printf ("%d\n", cost);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: