http://poj.org/problem?id=3126

Prime Path
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 11460 Accepted: 6498

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
此题超时了多次!这个要用记忆化搜索,记录下每次搜索到了的素数的最短路径,大于这个路径就不用搜索!
 
代码!
#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
struct node{
   int key;
   int step;
}temp;
bool prime[10000+1000];
int s[10000+1000];
int n;

void get_prime() {
   for (int i = 0; i < 10000; i ++) prime[i] = true;
   prime[0] = false;
   prime[1] = false;
   for (int i = 2; i < 10000; i ++) {
    if (prime[i]) {
        for (int j = i*i; j < 10000; j += i) {
            prime[j] = false;
        }
    }
   }
}

int change(int x, int i, int j) {
    if (i == 1) return x%1000+j*1000;
    if (i == 2) return j*100+x/1000*1000+x%100;
    if (i == 3) return x/100*100+x%10+j*10;
    if (i == 4) return x/10*10+j;
}
int main() {
   int x, y, t;
   get_prime();
   scanf("%d", &n);
   while (n --) {
    scanf("%d%d", &x, &y);
    if (x == y) {
        printf("0\n");
        continue;
    }
    memset(s, 100, sizeof(s));
     queue<node>q;
     temp.key = x;
     temp.step =0;
     q.push(temp);
     int ans = -1;
     while (!q.empty()) {
        if (q.front().key == y) {
            ans = q.front().step;
            break;
        }
        for (int i = 4; i >= 1; i --) {
            for (int j = 0; j < 10; j ++) {
                if (i == 1) {
                    if (j != 0) {
                        t = change(q.front().key, i, j);

                        if (prime[t]) {
                            if (q.front().step + 1 >= s[t]) continue;
                            if (t == y) {
                                ans = q.front().step+1;
                                break;
                            }
                            s[t] = q.front().step+1;
                            temp.key = t;
                            temp.step = q.front().step+1;
                            q.push(temp);
                        }
                    }
                } else {
                      t = change(q.front().key, i, j);
                      if (prime[t]) {
                        if (q.front().step + 1 >= s[t]) continue;
                        if (t == y) {
                            ans = q.front().step+1;
                            break;
                        }
                        s[t] = q.front().step+1;
                        temp.key = t;
                        temp.step = q.front().step+1;
                        q.push(temp);
                      }
                }
                if (ans != -1) break;
            }
            if (ans != -1) break;
        }
        if (ans != -1) break;
        q.pop();
     }
     printf("%d\n", ans);
   }
return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值