poj3126 电源一按 (素数打表+bfs)

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

题意:四位数a,b,对于a,每次只能变换一位,而且变换后的数必须为素数,问最少变换几次能变到b

上边给的例子:

1033 
1733 
3733 
3739 
3779 
8779 
8179

1033->8179 需要6步

思路:先欧拉素数筛打表,然后bfs(eg:对num来说,它有四个位可以变化,千位,百位,十位,个位,对于每一位又有9种可能,因为它不能再重复本身去)

代码:

import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Scanner;
class nod1{
	int x;
	int step;
}
public class Main {
	static final int max=10005;
	static boolean vis[]=new boolean[max];
	static int k=0;
	public static void Prime(){
		 int prime[]=new int[max];
		 Arrays.fill(vis, true);
		 vis[0]=vis[1]=false;
		 for(int i=2;i<max;i++){
			 if(vis[i])
				 prime[k++]=i;
			 for(int j=0;j<k&&i*prime[j]<max;j++){
				 vis[i*prime[j]]=false;
				 if(i%prime[j]==0)
					 break;
			 }
		 }
//		 for(int i=0;i<k;i++){
//			 System.out.println(prime[i]);
//		 }
	}
	public static int bfs(int a,int b){
		ArrayDeque<nod1> q=new ArrayDeque<nod1>();
		boolean vis2[]=new boolean[max];
		int t[]=new int[4];
		Arrays.fill(vis2, false);
		while(!q.isEmpty()){
			q.poll();
		}
		nod1 r1=new nod1();
		r1.x=a; r1.step=0;
		q.offer(r1);
		vis2[a]=true;
		while(!q.isEmpty()){
		    r1=q.poll();
		    if(r1.x==b){
			   return r1.step;
		    }
		    int num=r1.x;
		    t[0]=num/1000;
			t[1]=num/100%10;
			t[2]=num%100/10;
			t[3]=num%10;
		    for(int i=0;i<4;i++){
		    	int temp=t[i];
			    for(int j=0;j<10;j++){
				   int s=0;
				   if(t[i]!=j){
					   t[i]=j;
					   s=t[0]*1000+t[1]*100+t[2]*10+t[3];
				   }
				  if(s>=1000&&s<=9999&&vis[s]&&!vis2[s]){
					  nod1 r2=new nod1();
					  r2.x=s; r2.step=r1.step+1;
					  q.offer(r2);
					  vis2[s]=true;//一定要标记!!!
				  }
				  t[i]=temp;
			   }
		    }
		}
		return -1;
	}
    public static void main(String[] args) {
	  Prime();
	  Scanner scan=new Scanner(System.in);
	  int t=scan.nextInt();
	  while(t>0){
		  int a=scan.nextInt();
		  int b=scan.nextInt();
		  int ans=bfs(a,b);
		  if(ans==-1){
			  System.out.println("Impossible");
		  }
		  else{
			  System.out.println(ans);
		  }
		  t--;
	  }
}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小鱼爱吃火锅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值