您的位置:首页 > 其它

求21位数的水仙花数

2016-01-08 20:55 357 查看
import java.math.BigInteger;
import java.util.Scanner;
class Question10Think2OptimizeMustRemember{
publicstatic int size;
publicstatic int array[]={0,1,2,3,4,5,6,7,8,9};
publicstatic BigInteger powArray[] = new BigInteger[10]; // 记录0~9的size次方
publicstatic int usedTimes[]=new int[10];// 记录0~9的使用次数
publicstatic BigInteger iPowSizeMultiplyj[][]; //记录0到9中任意数字i的N次方乘以i出现的次数j的结果(i^N*j)
publicstatic BigInteger MAX; // size位的数字能表示的最大值
publicstatic BigInteger MIN; // size位的数字能表示的最小值
publicstatic void init() {// 用于初始化powArray[],MAX,MIN
for(int i = 0; i < 10; i++) {// 初始化powArray[]
powArray[i]= (new BigInteger("" + i)).pow(size);
}
MIN= (new BigInteger("10")).pow(size - 1); // 初始化最小值
MAX= (new BigInteger("10").pow(size).add(newBigInteger("-1")));// 初始化最大值
iPowSizeMultiplyj=newBigInteger[10][size+1]; //初始化iPowSizeMultiplyj[][]
for(int i = 0; i < 10; i++) {
iPowSizeMultiplyj[i][0]=BigInteger.valueOf(0);
for(int j = 1; j < size+1; j++) {
iPowSizeMultiplyj[i][j]=iPowSizeMultiplyj[i][j-1].add(powArray[i]);
}
}
}
publicstatic void exhaustion(int arrayIndex,int used,BigInteger current) {
if(current.compareTo(MAX)>1) {//超过最大值,递归结束
return;
}

if(used==size){//size位全部分配完毕
if(current.compareTo(MIN)<0){//已获得的值小于最小值
return;
}else{
Strings=current+"";
intavaliableValueUsed[]=new int[10];
for(int i = 0; i < s.length(); i++) {
avaliableValueUsed[s.charAt(i)-'0']++;
}
for(int i = 0; i < 10; i++) {
if(usedTimes[i]!=avaliableValueUsed[i]){
return;
}
}
System.out.println(current);
return;
}
}
if(arrayIndex==0){
usedTimes[0]=size-used;
exhaustion(-1,size, current);
usedTimes[0]=0;
return;
}
if(current.add(iPowSizeMultiplyj[arrayIndex][size-used]).compareTo(MIN)<0){
return;
}
if(arrayIndex>=0){
for(int i = 0; i <= size-used; i++) {
if(current.add(iPowSizeMultiplyj[arrayIndex][i]).compareTo(MAX)>0){
return;
}
usedTimes[arrayIndex]=i;
exhaustion(arrayIndex-1,used+i,current.add(iPowSizeMultiplyj[arrayIndex][i]));
usedTimes[arrayIndex]=0;
}
}else{
return;//1到9已分配完毕,不可再延伸了
}
}
publicstatic void main(String[] args) {
// Scannerscanner = new Scanner(System.in);
// Question10Think2.size= scanner.nextInt();
longstartTime = System.currentTimeMillis(); //程序开始时间
Question10Think2OptimizeMustRemember.size=21;
Question10Think2OptimizeMustRemember.init();

Question10Think2OptimizeMustRemember.exhaustion(9,0, BigInteger.valueOf(0));

longendTime = System.currentTimeMillis(); //程序结束时间
System.out.println((endTime-startTime)/1000f+"秒"); // 运行总时
}
}

运行结果:

128468643043731391252

449177399146038697307

19.062秒

 

方法二:

/*
* 求21位数的水仙花数
*/
import java.math.BigInteger;

public class Demo01_BigInteger {
// 求 每个 i 的 21 次方
public static BigIntegerp(int i){
BigInteger base =BigInteger.valueOf(i);
returnbase.pow(21);
}
public static voidji_suan(BigInteger[] pw,int[] nn){
BigInteger sum =BigInteger.ZERO;
for(inti=0;i<10;i++){
sum =sum.add(
pw[i].multiply(BigInteger.valueOf(nn[i])));
}
String s ="" + sum;
if(s.length()!=21)return;
// 确定各数字出现的多少次
int[] nn2 = newint[10];
for(inti=0;i<21;i++){
nn2[s.charAt(i)-'0']++;
}
for(inti=0;i<10;i++){
if(nn[i]!=nn2[i]) return;
}
System.out.println(s);
}
public static voidf(BigInteger[] pw, int[] nn, int cur, int use){
if(cur==9){
nn[9] = 21 -use;
ji_suan(pw,nn);
return;
}
// 对当前位置所有可能进行枚举
for(inti=0;i<21-use;i++){
nn[cur] =i;
f(pw,nn,cur+1,use+i);
}
}
public static voidmain(String[] args){
long startTime =System.currentTimeMillis(); // 程序开始时间
BigInteger pw[] =new BigInteger[10];
for(int i=0;i<pw.length;i++){
pw[i] =p(i);
}
int nn[] = newint[10];
f(pw,nn,0,0);
System.out.println("OK");
long endTime =System.currentTimeMillis(); // 程序结束时间
System.out.println((endTime-startTime)/1000f+"秒"); // 运行总时间
}
}


运行结果:

128468643043731391252 

449177399146038697307 

OK 

27.343秒

 

方法三:

import java.math.BigInteger;
import java.util.Arrays;
/**
* 如题,求解21位花朵数的解法,要求在3分钟之内计算完成花朵数: N位整数,它等于各个位的数字的N次方之和, *
* 例如有一个N位数字,a1a2a3a4.....aN = a1^N +a2^N+......aN^N
*
* @author hb
*/
public class FlowerNum {
private static int num =21;
private staticBigInteger[] table = new BigInteger[10];
private static int[]nums;
private static int[]a=new int[10];

public static voidmain(String[] args) {
long time =System.currentTimeMillis();
for (int i = 0; i< 10; i++)
table[i] =BigInteger.valueOf(i).pow(num);
nums = newint[num];
find(nums, 0, 0);
//f();
time =System.currentTimeMillis() - time;
System.out.println(time / 1000.0 + "s");
}
/**
* level表示第几位数,num表示第几位数的数字;
*/
public static voidfind(int[] nums, int level, int num) {
nums[level] =num;
if (level ==nums.length - 1) {
BigInteger big =sum(nums);//当level为20时,表示nums数组下标为20即21位数字满后求和;
int[] temp = getArray(big);//将得到的21位数和转化为整形数组;并返回;
if (check(nums,temp))//测试是否是21位,并将数组复制给nums数组;
System.out.println(big);//输出big数;
return;
}
for (int i =num; i< 10; i++)//递归;查找21位数字符合条件的数;
find(nums, level+ 1, i);
}
/**
* 检测长度,若符合条件就复制a2到a1;
* @param a1
* @param a2
* @return
*/
public static booleancheck(int[] a1, int[] a2) {
if (a1.length !=a2.length)
return false;
//Arrays.sort(Arrays.copyOf(a1, a1.length));
Arrays.sort(a1);
Arrays.sort(a2);
returnArrays.equals(a1, a2);
}
/**
* 得到nums数组的数做为table下标的数的和。并返回;
* @param nums
* @return
*/
public static BigIntegersum(int[] nums) {
BigInteger sum =BigInteger.ZERO;
for (int i = 0; i< nums.length; i++)
sum =sum.add(table[nums[i]]);
return sum;
}
/**
* 将BigInteger转化为int[]类型数据;
* @param big
* @return
*/
public static int[]getArray(BigInteger big) {
String s =String.valueOf(big);
char[] ch =s.toCharArray();
int[] res = newint[ch.length];
for (int i = 0; i< ch.length; i++)
res[i] = ch[i] -'0';
return res;
}

public static void f(){
for(a[0]=0;a[0]<=21;a[0]++){
for(a[1]=0;a[1]<=21-a[0];a[1]++){
for(a[2]=0;a[2]<=21-a[0]-a[1];a[2]++){
for(a[3]=0;a[3]<=21-a[0]-a[1]-a[2];a[3]++){
for(a[4]=0;a[4]<=21-a[0]-a[1]-a[2]-a[3];a[4]++){
for(a[5]=0;a[5]<=21-a[0]-a[1]-a[2]-a[3]-a[4];a[5]++){
for(a[6]=0;a[6]<=21-a[0]-a[1]-a[2]-a[3]-a[4]-a[5];a[6]++){
for(a[7]=0;a[7]<=21-a[0]-a[1]-a[2]-a[3]-a[4]-a[5]-a[6];a[7]++){
for(a[8]=0;a[8]<=21-a[0]-a[1]-a[2]-a[3]-a[4]-a[5]-a[6]-a[7];a[8]++){
a[9]=21-a[0]-a[1]-a[2]-a[3]-a[4]-a[5]-a[6]-a[7]-a[8];
BigIntegersum=BigInteger.ZERO;
for(inti=0;i<10;i++){
sum=sum.add(table[i].multiply(newBigInteger(String.valueOf(a[i]))));
}
if(String.valueOf(sum).length()==21){
Stringstr=sum.toString();
intb[]=new int[10];
for(intindex=0;index<str.length();index++){
intflag=str.charAt(index)-'0';
b[flag]+=1;
}
booleanf=true;
inti=0;
for(;;){
if(i==10)break;
if(b[i]!=a[i]){f=false;break;}
i++;
}
if(f)System.out.println(sum.toString());
}
}
}
}
}
}
}
}
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: