10.蓝桥杯之求21位数的水仙花数

3位数的水仙花数(先补一下什么叫水仙花数)
求100~999中的水仙花数,所谓水仙花数是一个三位数,它的各位数字的立方和等于该数,例如153是一个水仙花数,因为153=1^3 + 5^3 + 3^3.


N=21时,所有满足条件的花朵数。注意:这个整数有21位,它的各个位数字的21次方之和正好等于这个数本身。也就是21的水仙花数


class Question10Think2OptimizeMustRemember {
	public static int size;
	public static int array[]={0,1,2,3,4,5,6,7,8,9};
	public static BigInteger powArray[] = new BigInteger[10]; // 记录0~9的size次方
	public static int usedTimes[]=new int[10];// 记录0~9的使用次数
	public static BigInteger iPowSizeMultiplyj[][]; //记录0到9中任意数字i的N次方乘以i出现的次数j的结果(i^N*j)
	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")));// 初始化最大值
		iPowSizeMultiplyj=new BigInteger[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]);
			}
		}
	}
	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(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已分配完毕,不可再延伸了
		}
	}
	public static void main(String[] args) {
//		Scanner scanner = new Scanner(System.in);
//		Question10Think2.size = scanner.nextInt();
		long startTime = System.currentTimeMillis();	// 程序开始时间
		Question10Think2OptimizeMustRemember.size=21;
		Question10Think2OptimizeMustRemember.init();
		
		Question10Think2OptimizeMustRemember.exhaustion(9, 0, BigInteger.valueOf(0));
		
		
		long endTime = System.currentTimeMillis();	// 程序结束时间
		System.out.println((endTime-startTime)/1000f+"秒");	// 运行总时
	}
}


支付宝扫红包,让我能够买杯咖啡,继续创作,谢谢大家!
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值