— 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.
這道題就是一個暴力題,我們首先把所有的四位質數存起來(是質數就爲1,不是質數就爲0),
然後在一位一位的枚舉並改動(改出的數是質數我們才改,不然就違背題意了),最後求出答案時就挑出。當然,我說的暴力不是真正的暴力,而是要一位一位地枚舉。當然,因爲這道題是一個最短路徑問題,所以我們也應該用寬搜解決這道題。
#include<iostream>
#include<queue>
#include<cmath>
using namespace std;
queue<int>sm;
int a[10000]={0},d[10000]={0},s,t,n;
int search(int f1,int f2){
for(int i=1000;i<=9999;i++)//初始化
{
d[i]=123456789;
}
d[f1]=0;
sm.push(f);
while(sm.size()){
int p=sm.front();sm.pop();
if(p==f2){
break;
}
int h[5]={0};
int l=p,wei=0;
while(l){
h[++wei]=l%10;
l/=10;
} //存下每一位
for(int i=0;i<=9;i++){
int ss=i+h[2]*10+h[3]*100+h[4]*1000; //改個位
if(a[ss]==1&&d[ss]>(1+d[p])){
d[ss]=d[p]+1;
sm.push(ss);
}
}
for(int i=0;i<=9;i++){
int ss=h[1]+i*10+h[3]*100+h[4]*1000; //改十位
if(a[ss]==1&&d[ss]>(1+d[p])){
d[ss]=d[p]+1;
sm.push(ss);
}
}
for(int i=0;i<=9;i++){
int ss=h[1]+h[2]*10+i*100+h[4]*1000; //改百位
if(a[ss]==1&&d[ss]>(1+d[p])){
d[ss]=d[p]+1;
sm.push(ss);
}
}
for(int i=1;i<=9;i++){//改千位,千位不能爲0!
int ss=h[1]+h[2]*10+h[3]*100+i*1000;
if(a[ss]==1&&d[ss]>(1+d[p])){
d[ss]=d[p]+1;
sm.push(ss);
}
}
}
return d[f2];
}
int main() {
cin>>n;
for(int i=1000;i<=9999;i++){//存下所有四位質數
int k=sqrt(i);
for(int j=2;j<=k;j++){
if(i%j==0){
goto haha;
}
}
a[i]=1;
haha:;
}
for(int i=1;i<=n;i++){
cin>>s>>t;
int ll=search(s,t);
if(ll!=123456789)
cout<<ll<<endl;
else cout<<"Impossible"<<endl;//其實沒有這種情況
while(sm.size()){//每執行完一次就要清空,不然會影響下一次的結果
sm.pop();
}
}
}