21位数的花朵数

import java.math.BigInteger;


//花朵数
public class Flower {
	
	/*
	 *   先求出 0- 9 的 21 次方 ,用BigInteger 的数组进行保存
	 *   使用一个数组保存: 0- 9 在 21 位数中出现的次数
	 *   
	 *   使用递归,找到每个数出现次数的可能,找到一种结果计算一次; 看是否符合条件
	 * 
	 * */
	
	//每次求出 0-9 的 21 次方
	public static BigInteger p(int a){
		BigInteger base = BigInteger.ONE;
		for(int i=0;i<21;i++){
			base = base.multiply(BigInteger.valueOf(a));
		}
		return base;
	}
	
	//用于计算
	public static void ji_suan(BigInteger[] pwd,int[] nn){
		// 求和
		BigInteger sum = BigInteger.ZERO;
		for(int i=0;i<10;i++){
			sum=sum.add(pwd[i].multiply(BigInteger.valueOf(nn[i])));
		}
		
		String s=""+sum ;		//转换成字符
		
		if(s.length()!=21){
			return;
		}
		
		//确定和中各数字出现多少次
		int[] nn2 = new int[10];
		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);
		
	}
	
	//递归  :判断每个数出现次数的可能
	public static void f(BigInteger[] pwd,int[] nn,int current,int use){
		
		if(current==9){		//前面的数都定下来了,那么 9 出现的次数
			nn[current]=21-use;
			ji_suan(pwd,nn);	//此时nn 里面保存的是此时的一种情况
			return;
		}
		
		for(int i=0;i<=21-use;i++){
			nn[current] = i;	//记录当前数出现的次数
			f(pwd,nn,current+1,use+i);
		}
	}
	
	public static void main(String[] args){
		// 0- 9 的 21 次方
		BigInteger[] pwd = {p(0),p(1),p(2),p(3),p(4),p(5),p(6),p(7),p(8),p(9)};
		// 0 - 9 出现的次数
		int[] nn = new int[10];
		f(pwd,nn,0,0);
		
	}
}

你可能感兴趣的:(ACM)