问题就不描述了,简单说下思路。
思路:(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