Prime Path

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.
這道題就是一個暴力題,我們首先把所有的四位質數存起來(是質數就爲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();
	}
}
}

發佈了29 篇原創文章 · 獲贊 12 · 訪問量 4270
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章