• 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();
    	}
    }
    }

  • 相关阅读:
    uboot如何检测XC2440是从Nand或Nor启动
    uboot中的快捷菜单的制作说明
    Android存储数据方式
    SharedPreferences详解
    (转载)Android理解:显式和隐式Intent
    使用 Fresco加载图片
    script "text/template"
    网页动画插件---Super Scrollorama , TweenMax 和skrollr
    Android控件之HorizontalScrollView 去掉滚动条
    android编程取消标题栏方法(appcompat_v7、Theme.NoTitleBar)
  • 原文地址:https://www.cnblogs.com/c201904xyorz/p/9990804.html
Copyright © 2020-2023  润新知