一个N位的十进制正整数,如果它的每个位上的数字的N次方的和等于这个数本身,则称其为花朵数。 例如:
当N=3时,153就满足条件,因为1^3+5^3+3^3=153,这样的数字也被称为水仙花数(其中,“^”表示乘方,5^3表示5的3次方,也就是立方)。 当N=4时,1634满足条件,因为1^4+6^4+3^4+4^4=1634. 当N=5时,92727满足条件。
实际上,对N的每个取值,可能有多个数字满足条件。
程序的任务是:求当N=21时,所有满足条件的水仙花数。注意:这个整数有21位, 它的各个位数字的21次方之和正好等于这个数本身。
当N=3时,153就满足条件,因为1^3+5^3+3^3=153,这样的数字也被称为水仙花数(其中,“^”表示乘方,5^3表示5的3次方,也就是立方)。 当N=4时,1634满足条件,因为1^4+6^4+3^4+4^4=1634. 当N=5时,92727满足条件。
实际上,对N的每个取值,可能有多个数字满足条件。
程序的任务是:求当N=21时,所有满足条件的水仙花数。注意:这个整数有21位, 它的各个位数字的21次方之和正好等于这个数本身。
如果满足条件的数字不只有一个,请从小到大输出所有符合条件的数字,每个数字占一行。因为这个数字很大,请注意解法时间上的可行性。要求程序在3分钟内运行完毕。
解题思路: 还是暴力。
import java.math.BigInteger;
/*
* 21位水仙花数!
*
*
*/
public class Asist
{
static BigInteger hash[] = new BigInteger[10];
public static void main(String[] args)
{
long t = System.currentTimeMillis();
// 打表
table();
int a1[] = new int[10];
dfs(a1, 0, 21);
System.out.println(System.currentTimeMillis()-t + "ms");
}
private static void table()
{
for (int i = 0; i < 10; i++)
{
hash[i] = pow1(i, 21);
}
}
private static void dfs(int[] a1, int k, int ws)
{
if (ws == 0)
{
test(a1);
}
else if (k == a1.length-1)
{
a1[k] = ws;
test(a1);
}
else{
for (int i = 0; i <= ws; i++)
{
a1[k] = i;
dfs(a1, k + 1, ws-i);
a1[k] = 0;
}
}
}
private static void test(int[] a1)
{
int b1[] = new int[10];
BigInteger sum = new BigInteger("0");
for (int i = 0; i < 10; i++)
{
sum = sum.add(hash[i].multiply(new BigInteger(a1[i]+"")));
}
if (sum.toString().length() != 21) return;
char[] c1 = sum.toString().toCharArray();
for (int i = 0; i < c1.length; i++)
{
b1[c1[i]-'0']++;
}
for (int i = 0; i < 10; i++)
{
if (b1[i] != a1[i]) return;
}
System.out.println(sum);
}
// 求幂
private static BigInteger pow1(int i, int j)
{
BigInteger sum = BigInteger.ONE;
BigInteger temp = new BigInteger(i+"");
while(j != 0)
{
if ((j & 1) == 1) sum = sum.multiply(temp);
temp = temp.multiply(temp);
j >>= 1;
}
return sum;
}
}
</pre><pre name="code" class="java">运行结果:
128468643043731391252
449177399146038697307
63444ms