蓝桥杯 21位的水仙花数

水仙花数是指一个 n 位数 ( n≥3 ),它的每个位上的数字的 n 次幂之和等于它本身。(例如:1^3 + 5^3+ 3^3 = 153)

import java.math.BigInteger;
import java.util.Scanner;

public class Main{
	public static int size;
	public static int array[]={0,1,2,3,4,5,6,7,8,9};
	//记录0-9的size次方
	public static BigInteger powArray[]=new BigInteger[10];
	//记录0-9的使用次数
	public static int usedTimes[]=new int[10];
	//i^N*j
	public static BigInteger isPowSizeMultiply[][];
	public static BigInteger MAX;//size位的数字能表示的最大值
	public static BigInteger MIN;//size位的数字能表示的最小值
	
	public static 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(new BigInteger("-1"));//初始化最大值
		
		isPowSizeMultiply=new BigInteger[10][size+1];
		for(int i=0;i<10;i++){
			isPowSizeMultiply[i][0]=BigInteger.valueOf(0);
			for(int j=1;j<size+1;j++){
				isPowSizeMultiply[i][j]=isPowSizeMultiply[i][j-1].add(powArray[i]);
			}
		}
	}
	
	public static 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{
				String s=current+"";
				int avaliableValueUsed[]=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(isPowSizeMultiply[arrayIndex][size-used]).compareTo(MIN)<0){
			return;
		}
		
		if(arrayIndex>=0){
			for(int i=0;i<=size-used;i++){
				if(current.add(isPowSizeMultiply[arrayIndex][i]).compareTo(MAX)>0){
					return;
				}
				usedTimes[arrayIndex]=i;
				exhaustion(arrayIndex-1,used+i,current.add(isPowSizeMultiply[arrayIndex][i]));
				usedTimes[arrayIndex]=0;
			}
		}else{
			return;//1-9已经分配完毕,不可再延伸
		}
	}
	
	public static void main(String[] args){
		long startTime=System.currentTimeMillis();//程序开始的时间
		size=21;
		init();
		exhaustion(9,0,BigInteger.valueOf(0));
		long endTime=System.currentTimeMillis();//程序结束的时间
		System.out.println((endTime-startTime)/1000f+"秒");
	}
	
	
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值