问题就不描述了,简单说下思路。
思路:(1)暴力枚举21位数,然后一个个的计算,虽然能解,但是,时间不允许的。
(2)枚举 0 -9 这10个数子在这个21位数中出现的次数。得到一种解后,再计算出这个21位数,然后与原来得到的解对比,看看0 - 9出现的次数是否一样,是,这个21位数就是一个解。用时不到30s。
AC代码:
import java.math.BigInteger; /*21位水仙花数 * 枚举每个数字出现的次数 * */ public class T08 { //记录0 - 9 这几个数的21次方 static BigInteger[] num = new BigInteger[10]; public static void main(String[] args) { //算出0 - 9 的21次方 pf(num); //枚举0 - 9出现的个数,存储在count中。 int[] count = new int[10]; f(count,0,21); } public static void f(int[] count,int index,int max) { if(index == 9) { count[index] = max; //计算结果 jisuan(count,num); } else { for(int i = 0;i<=max;i++) { count[index] = i; f(count,index+1,max - i); } } } private static void jisuan(int[] count,BigInteger[] num) { BigInteger ans = new BigInteger("0"); //算出该状态下的21位数 for(int i = 0;i<10;i++) { ans = ans.add(num[i].multiply(new BigInteger(""+count[i]))); } String str = ans.toString(); //如果不是21位,结束 if(str.length()!=21) return; //得到该21位数中 0 - 9 出现的次数 int[] ans2 = new int[10]; for(int i = 0;i<21;i++) { ans2[str.charAt(i) - '0']++; } //与原来的枚举结果对比 for(int i = 0;i<10;i++) { if(ans2[i] != count[i]) return; } sop(str); } private static void sop(String str) { System.out.println(str); } //计算各个数的21次方 public static void pf(BigInteger[] num) { for(int i = 0;i<10;i++) { num[i] = new BigInteger(""+i); num[i] = num[i].pow(21); } } }
原文地址:http://blog.csdn.net/u013451048/article/details/44727097