F - Prime Path POJ - 3126

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 <cstdlib>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <vector>
#include <cstring>

using namespace std;
typedef long long ll;
typedef struct node {

} node;
const int maxn = 1e5 + 10;
int t, n, m, x, y, cnt;
int vis[maxn], sim[5],privis[maxn], pri[maxn], che[maxn];

void prime() {
    memset(privis, 0, sizeof(privis));
    privis[0] = privis[1] = 1;
    cnt = 0;
    for(int i = 2; i < 10000; i++) {
        if(!privis[i]) {
            pri[cnt++] = i;
        }
        for(int j = 1; j < cnt && i * pri[j] < 10000; j++) {
            privis[i * pri[j]] = 1;
            if(i % pri[j] == 0) {
                break;
            }
        }
    }
}
int BFS() {
    queue<int> Q;
    memset(vis, 0, sizeof(vis));
    Q.push(n);
    vis[n] = 1;
    while(!Q.empty()) {
        x = Q.front();
//        cout << x << endl;
        Q.pop();
        if(x == m) {
            return vis[m];
        }
        int xx = x;
        for(int i = 3; i >= 0; i--) {
            sim[i] = xx % 10;
            xx /= 10;
        }
        for(int i = 0; i < 4; i++) {
            if(i == 0) {
                for(int j = 0; j < 10; j++) {
                    y = j * 1000 + sim[1] * 100 + sim[2] * 10 + sim[3];
                    if(y >= 1000)
                        if(pri[y] && !vis[y]) {
                            Q.push(y);
                            vis[y] = vis[x] + 1;
                        }
                }
            } else if(i == 1) {
                for(int j = 0; j < 10; j++) {
                    y = sim[0] * 1000 + j * 100 + sim[2] * 10 + sim[3];
                    if(y >= 1000)
                        if(pri[y] && !vis[y]) {
                            Q.push(y);
                            vis[y] = vis[x] + 1;
                        }
                }
            } else if(i == 2) {
                for(int j = 0; j < 10; j++) {
                    y = sim[0] * 1000 + sim[1] * 100 + j * 10 + sim[3];
                    if(y >= 1000)
                        if(pri[y] && !vis[y]) {
                            Q.push(y);
                            vis[y] = vis[x] + 1;
                        }
                }
            } else {
                for(int j = 0; j < 10; j++) {
                    y = sim[0] * 1000 + sim[1] * 100 + sim[2] * 10 + j;
                    if(y >= 1000)
                        if(pri[y] && !vis[y]) {
                            Q.push(y);
                            vis[y] = vis[x] + 1;
                        }
                }
            }
        }
    }
    return -1;
}
int main() {
    ios::sync_with_stdio(false);
//    int pos = 0;
//    for(int i = 2; i < 100000; i++) {
//        if(!che[i]) {
//            pri[pos++] = i;
//        }
//        for(int j = 0; j < pos && i * pri[j] < 10000; j++) {
//            che[i * pri[j]] = 1;
//            if(i % pri[j] == 0) {
//                break;
//            }
//        }
//    }
    prime();
    cin >> t;
    while(t--) {
        cin >> n >> m;
        if(n == m) {
            cout << 0 << '\n';
        } else {
            int ans = BFS();
            if(ans != -1) {
                cout << ans - 1 << '\n';
            } else {
                cout << "Impossible\n";
            }
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值