package homework; import java.math.BigInteger; public class Main { public static void main(String[] args) { long start = System.currentTimeMillis(); int[] a = new int[10]; BigInteger[] b = new BigInteger[10]; // 计算0~910个数的21次方并且存储在数组b中 b[0] = BigInteger.ZERO; b[1] = BigInteger.ONE; for (int i = 2; i <= 9; i++) { b[i] = BigInteger.valueOf(i).pow(21); } // 调用函数 ss(b, a, 0, 21); long end = System.currentTimeMillis(); double sec = (end - start) / 1000.0; System.out.println(sec + "秒"); } // index现在进行到数组的第几个元素 // left这个元素出现的次数最多有多少次 // a数组的下标表示0~9这10个数字,a数组元素的值表示下标数字出现的次数 private static void ss(BigInteger[] b, int[] a, int index, int left) { if (index == 9) { // 一次深度优先走完 // 刚好21次也分配完了 a[9] = left; if (a[9] < 10) { // 9的21次方出现的次数不能超过10次,因为9的21次方是21位数 BigInteger ret = BigInteger.ZERO; for (int i = 0; i < a.length; i++) { // 一旦结果超过21位,立即跳出循环 if (ret.toString().length() > 21) { ret = null; break; } // 把每个数字出现的次数乘以它的21次方,然后累加起来 if (a[i] != 0) { ret = ret.add(b[i].multiply(BigInteger.valueOf(a[i]))); } } if (ret != null && ret.toString().length() == 21) { // 进一步验证每个数字出现的次数是否和a数组一致 String x = ret.toString(); // System.out.println(x); int[] c = new int[10]; for (int i = 0; i < x.length(); i++) { c[x.charAt(i) - '0']++; } // 对比两个数组,一致说明找到答案 boolean isRight = true; for (int i = 0; i < c.length; i++) { if (a[i] != c[i]) { isRight = false; break; } } if (isRight) { System.out.println(x); } } } return; } // 为第index个a数组元素分配次数 for (int i = 0; i <= left; i++) { a[index] = i; ss(b, a, index + 1, left - i); } } }