您的位置:首页 > 其它

找出21位的水仙数

2016-03-14 21:15 260 查看
package cn.heima;

/**

* 找出21位的水仙数?

* 思路:由于21位很大很大了不能用普通的循环来做

* 分析可知无论多大的数其每一位数都是0-9的数所以我们可以反过来想

* 1.首先我们用BigInteger来存放数

* 2.用一个BigInteger数组来存放0^21--9^21

* 3.再用一数组来存放0^21--9^21出现次数

*/

import java.math.BigInteger;

public class Suixianhua {

public static void main(String[] args) {

BigInteger[] pp =new BigInteger[10];//定义一个数组用来存放0^21-9^21

int[] c = new int[10];//定义一个数组用来存放0^21-9^21出现的次数

int n = 21;

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

pp[i] =p(i,n);//存储0^21,1^21,2^21...到数组中

}

long startTime = System.currentTimeMillis();

g(pp,c,0,0,n);//开始求解

long endTime = System.currentTimeMillis();

System.out.println((endTime-startTime)/1000f +"秒");

}

public static BigInteger p(int i,int n){

BigInteger base = BigInteger.valueOf(i);//生成一个为i的BigInteger对象

return base.pow(n);//将BigInteger对象乘以它的n次

}

public static void g(BigInteger[] p,int[] c,int index ,int user,int n){

if(index==9){//如果已经存到第9的数时

c[9]=n - user;//它的位数为余下的位数及21-已经用的位数

suan(c,p,n);//开始下一步计算

return;//出栈

}else{

for(int i=0;i<n-user;i++){//它们出现最小次数为0---最大次数是21-前面数用的

c[index]=i;//0,1,2,3..中在其中出现的次数

g(p,c,index+1,user+i,n);//注意在这里user表示用了多少位所以要加i

}

}

}

public static void suan(int[] c, BigInteger[] p,int n) {

// TODO Auto-generated method stub

int[] nb = new int[10];

BigInteger sum = BigInteger.ZERO;//生成一个位0的BigInteger对象

for(int i=0;i<10;i++){//sum为其和对象是重0^21-9^21的次数和其对应相乘后再相加

sum=sum.add(p[i].multiply(BigInteger.valueOf(c[i])));

}

String ss =sum.toString();//把sum转换为string类型

if(ss.length()!=n) return;//如果生成sum的位数没有21直接return掉

for(int i=0;i<ss.length();i++){//如果有再统计sum0-9出现次数

nb[ss.charAt(i)-'0']++;

}

for(int i=0;i<=9;i++){//如果某一位出现次数不同直接return

if(nb[i]!=c[i])

return;

}

System.out.println(ss);//能运行到这说明一切都ok输出

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: