小森今天接到了一个任务,要为图森未来在图森市(Tucson)的卡车更换牌照。
因为图森市的特殊规定,合法的车牌号都要满足:
- 车牌号共有六位;
- 车牌号的每一位都是一个0-9中的数字;
- 车牌号组成的六位数(可以包含前导0,如000017即为17)是一个素数。
一次合法的更换是:某个合法的车牌号ABCDEF通过替换其中的一个数字(例如E)变成一个新的车牌号(ABCDXF),且新的车牌号也要是合法的。
现在小森想知道,给出任意两个合法的车牌号,前者最少通过多少次合法的更换可以变成后者?
输出的第一行是一个小于等于100的正整数n,表示测试数据的组数。
接下来的n行每行包含两个六位(可能包含前导0)的正整数,为两个合法的车牌号。
输出包含n行,每行有一个整数,表示对于每一组数据最少的合法更换的次数。
如果某组数据不存在一种可以合法更换车牌号的方式,在对应行输出-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; } }