给一个数不包含前导0的数n,现在将n的各位数字的顺序重组,在这些数中,有多少个数是m的倍数?
例如112,重组后有三个数:112,121,211
暴力回溯 超时 这数据太大了 import java.util.ArrayList; import java.util.Arrays; import java.util.Scanner; public class Main{ static int count = 0; public static void main(String[] args) { Scanner sc = new Scanner(System.in); String str = sc.nextLine(); String[] s = str.split(" "); char[] ch = s[0].toCharArray(); Arrays.sort(ch); int m = Integer.parseInt(s[1]); //int count = 0; boolean[] used = new boolean[ch.length]; ArrayList<Character> path = new ArrayList<>(); backtracking(ch, used, path, m); System.out.println(count); } public static void backtracking(char[] ch, boolean[] used, ArrayList<Character> path, int m) { if(path.size() == ch.length) { if(path.get(0) == '0') return; StringBuilder bui = new StringBuilder(); for(Character c : path) { bui.append(c); } int ss = Integer.parseInt(bui.toString()); if(ss % m == 0) count++; //System.out.println(count); return; } for (int i = 0; i < ch.length; i++) { if (i > 0 && ch[i] == ch[i - 1] && used[i - 1] == false) { continue; } //如果同⼀树⽀nums[i]没使⽤过开始处理 if (used[i] == false) { used[i] = true;//标记同⼀树⽀nums[i]使⽤过,防止同一树枝重复使用 path.add(ch[i]); backtracking(ch, used, path, m); path.remove(path.size() - 1);//回溯,说明同⼀树层nums[i]使⽤过,防止下一树层重复 used[i] = false;//回溯 } } } }
import java.math.BigInteger; import java.util.*; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); String[] s = in.nextLine().split(" "); char[] c = s[0].toCharArray(); Arrays.sort(c); v = new boolean[c.length]; back(c, Integer.parseInt(s[1])); System.out.println(res); } // 数字重排列-回溯爆搜 ac不了全部 static boolean[] v; static StringBuilder select = new StringBuilder(); static int res = 0; public static void back(char[] c, int m) { if (select.length() == c.length) { if (select.charAt(0) == '0') return; // 有前导0不要 BigInteger i = new BigInteger(select.toString()); if (i.mod(BigInteger.valueOf(m)).equals(BigInteger.ZERO)) { res++; } return; } for (int i = 0; i < c.length; i++) { if (i > 0 && c[i] == c[i-1] && !v[i-1]) continue; // 剪枝 if (!v[i]) { v[i] = true; select.append(c[i]); back(c, m); v[i] = false; select.deleteCharAt(select.length()-1); } } } }
/** * 不知道如何退出 例子只过 5个 **/ import java.util.*; public class Main{ public static void main(String[] args){ Scanner sc = new Scanner(System.in); String n = sc.next(); int m = sc.nextInt(); // 对n进行重组 有多少个是m的倍数 // 对n的每位数放入数组中 0-9 各多少个 int[] arr = method(n); int g = m; int count = 0; while(true){ g = g + m; int[] arr1 = method2(g); // 不知道 如何退出 求指点 if(g > 1000000){break;} boolean flag = true; for(int i = 0; i < 10; i++){ if(arr[i] != arr1[i]){ flag = false; break; } } if(flag){ count++; } } System.out.println(count); } static int[] method(String n){ int[] arr = new int[10]; for(int j = 0; j < n.length(); j++){ char c = n.charAt(j); int i = c - '0'; arr[i]++; } return arr; } static int[] method2(int n){ int[] arr = new int[11]; int len = 0; while(n > 0){ int i = n % 10; n = n / 10; arr[i]++; len++; } arr[10] = len; return arr; } }