首页 > 试题广场 >

卡车牌照(两个方向二选一作答,非Python)

[编程题]卡车牌照(两个方向二选一作答,非Python)
  • 热度指数:61 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
小森今天接到了一个任务,要为图森未来在图森市(Tucson)的卡车更换牌照。

因为图森市的特殊规定,合法的车牌号都要满足:
  • 车牌号共有六位;
  • 车牌号的每一位都是一个0-9中的数字;
  • 车牌号组成的六位数(可以包含前导0,如000017即为17)是一个素数。
同时,图森市允许为一辆卡车更换牌照,但是更换的过程也要满足规定。
一次合法的更换是:某个合法的车牌号ABCDEF通过替换其中的一个数字(例如E)变成一个新的车牌号(ABCDXF),且新的车牌号也要是合法的。

现在小森想知道,给出任意两个合法的车牌号,前者最少通过多少次合法的更换可以变成后者?

输入描述:
输出的第一行是一个小于等于100的正整数n,表示测试数据的组数。
接下来的n行每行包含两个六位(可能包含前导0)的正整数,为两个合法的车牌号。


输出描述:
输出包含n行,每行有一个整数,表示对于每一组数据最少的合法更换的次数。
如果某组数据不存在一种可以合法更换车牌号的方式,在对应行输出-1。
示例1

输入

1
134503 834703

输出

2

说明

134503 -> 834503 -> 834703,共2步。

备注:
对于30%的数据,全部车牌号的前两位一定都是0,且存在一个最优转换的方式,使得转换过程中所有生成的车牌号前两位也都是0。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.*;

public class Main{
    static boolean[] prime;
    static{
        prePro();
    }
    public static void main(String[] args) throws IOException {
        BufferedReader sc = new BufferedReader(new InputStreamReader(System.in), 1000000);
        int T = Integer.parseInt(sc.readLine());
        while(T-- > 0){
            String[] strs = sc.readLine().split(" ");
            System.out.println(h(Integer.parseInt(strs[0]), Integer.parseInt(strs[1])));
        }
    }
    private static void prePro(){
        int n = (int)1e6;
        prime = new boolean[n + 1];
        Arrays.fill(prime, true);
        for(int i = 2; i <= n; i++){
            if(prime[i]){
                for(int j = 2 * i; j <= n; j += i){
                    prime[j] = false;
                }
            }
        }
    }
    static int[] temp = {1, 10, 100, 1000, 10000, 100000, 1000000};
    private static int h(int n1, int n2){
        if(n1 == n2){
            return 0;
        }
        Set<Integer> seen = new HashSet<>();
        Queue<Integer> queue = new ArrayDeque<>();
        queue.add(n1);
        int step = 0;
        while(!queue.isEmpty()){
            int size = queue.size();
            while(size-- > 0){
                int num = queue.poll();
                //6 位进行改变
                for(int i = 0; i < 6; i++){
                    int cur = num / temp[i + 1] * temp[i + 1] + num % temp[i];
                    for(int j = 0; j <= 9; j++){
                        cur += j * temp[i];
                        if(cur == n2){
                            return step + 1;
                        }
                        if(prime[cur] && !seen.contains(cur)){
                            seen.add(cur);
                            queue.add(cur);
                        }
                        cur -= j * temp[i];
                    }
                }
            }
            step++;
        }
        return -1;
    }
}

发表于 2020-08-25 14:18:30 回复(0)