java花朵数_花朵数的研究 - MondChan的个人空间 - OSCHINA - 中文开源技术交流社区...

package mc;

import java.math.BigInteger;

import org.omg.PortableServer.ForwardRequestHelper;

/*

花朵数的研究

一个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位,可能不只有一个,请从小到大输出所

有符合条件的数字,每个数字占一行。

因为这个数字很大,请注意解法时间上的可行性。

*/

public class Num_of_Flowers {

/**

* @param args

*/

public static void main(String[] args) {

// TODO Auto-generated method stub

//0~9 每个数字的21次方

BigInteger[] pw={p(0),p(1),p(2),p(3),p(4),p(5),p(6),p(7),p(8),p(9)};

//0~9每个数字在21位位数中出现的次数

int[] nn=new int[10];

//算法核心:21个名额中:0~9每个数字出现的次数进行“大排列”

f(pw,nn,0,0);

}

//求解核心:利用递归方式遍历所有数字出现次数的可能

private static void f(BigInteger[] pw, int[] nn, int cur, int use) {

// TODO Auto-generated method stub

//选到了最后一个数字

if(cur==9)

{

nn[9]=21-use;

ji_suan(pw,nn);

return;

}

//对当前位置的所有可能进行枚举

for(int i=0;i<21-use;i++)

{

nn[cur]=i;

f(pw, nn, cur+1, use+i);

}

}

//传入的是0~9的各个21次方的值以及每个数字出现的次数。

private static void ji_suan(BigInteger[] pw, int[] nn) {

// TODO Auto-generated method stub

//求和

BigInteger sum=BigInteger.ZERO;

for(int i=0;i<10;i++)

{

//求pw[]里面的数字值(已经求了21次方的和)在nn[]中出现的次数,然后再乘积求和

sum=sum.add(pw[i].multiply(BigInteger.valueOf(nn[i])));

}

String s=""+sum;

//如果sum的长度小于或大于21,可以直接不用做下一步考虑,直接返回。

if(s.length()!=21) return;

//确定和中各个数字出现多少次

int[] nn2=new int[10];

//统计0~9数字在结果中出现的次数

for(int i=0;i<21;i++)

{

nn2[s.charAt(i)-'0']++;

}

//测试是否与nn[]中各个对应位置数目相同

for(int i=0;i<10;i++)

{

if(nn[i]!=nn2[i])return;

}

//完全匹配!打印结果

System.out.println(s);

}

//求x的21次方

private static BigInteger p(int x) {

// TODO Auto-generated method stub

BigInteger base=BigInteger.ONE;

for(int i=0;i<21;i++)

{

base=base.multiply(BigInteger.valueOf(x));

}

return base;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值