import java.math.BigInteger;
import java.util.Arrays;
/**
* @author wangfengyang
* 求21位花朵数
* 思路:
* 分别对0-9进行选择,每个选择x个,所有x的和等于21
* 根据选择的数字个数求这个数temp
* 判断这个数temp是不是满足每个数字选择的个数
* 步骤:
* 1.在数组countArr的每个元素中填充一个数x(0<=x<=21)
* 数组位置编号:0, 1, 2, 3, 4, 5, 6, 7, 8, 9
* 例如countArr = {1, 2, 3, 0, 5, 0, 2, 1, 3, 4};
* 数组中的值的意思: 1个0,2个1,3个2,0个3,5个4,0个5,2个6,1个7,3个8,4个9
* 2.根据数组中的元素求要组合的这个数
* temp=1*0^21+2*1^21+3*2^21+0*3^21+5*4^21+0*5^21+2*6^21+1*7^21+3*8^21+4*9
* 3.判断这个数temp是不是符合条件(1个0,2个1,3个2,0个3,5个4,0个5,2个6,1个7,3个8,4个9)
*/
public class FlowerCount {
private static final int N = 21;
private static final int LEN = 10;
public static int[] countArr = new int[LEN];
public static BigInteger[] arr = new BigInteger[LEN];
public static final BigInteger MAX = new BigInteger("1000000000000000000000");
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
init(N);
showArr(N);
System.out.println("startTime=0");
recursive(0, N);
System.out.println("endTime="+(System.currentTimeMillis()-startTime)/1000+"s");
}
private static void showArr(int n) {
for(int i=0; i<arr.length; i++) {
System.out.println(arr[i]);
}
}
/**
* 初始化arr数组
* arr[i] = i^n(例如:5^21)
*/
private static void init(int n) {
arr[0] = BigInteger.ZERO;
arr[1] = BigInteger.ONE;
BigInteger temp, result;
for(int i=2; i<arr.length; i++) {
temp = BigInteger.valueOf(i);
result = temp;
for(int j=2; j<=n; j++) {
result = result.multiply(temp);
}
arr[i] = result;
}
}
/**
* 递归的搜索
* @param cur cur是countArr数组的当前位置(0<=cur<10)
* @param len len是当前还有多少位没有使用(0<=len<=21)
* countArr数组是保存组成的21数中0-9使用的个数
* countArr中所有和等于21的时候才表示能够组成一个21位的数
*/
private static void recursive(int cur, int len) {
if(cur==LEN || len==0) {//当len==0的时候说应已经有一个21位的数
if(len == 0) {
//showCountArr();
String resultStr = handle();
if(!"n".equals(resultStr)) {
System.out.println(resultStr);
}
}
} else {
for(int i=0; i<=len; i++) {
countArr[cur] = i;
recursive(cur+1, len-i);
countArr[cur] = 0;
}
}
}
/**
*
* @return if是21位的数就返回该数
* else返回"n",表示no
*/
private static String handle() {
BigInteger temp = BigInteger.ZERO;
for(int i=LEN-1; i>=0; i--) {
if(countArr[i] != 0) {
temp = temp.add(arr[i].multiply(BigInteger.valueOf(countArr[i])));
}
if(temp.compareTo(MAX) >= 0) {//和不能>=MAX(10^21)
return "n";
}
}
String str = temp.toString();
if(str.length() != N) {//这个数的长度应该是21位
return "n";
}
int[] countArrCopy = Arrays.copyOf(countArr, countArr.length);
for(int i=0; i<str.length(); i++) {//判断这个21位数是不是满足要求
int index = str.charAt(i)-'0';
if(countArrCopy[index]-- <= 0) {
return "n";
}
}
return str;
}
private static void showCountArr() {
for(int i=0; i<countArr.length; i++) {
System.out.print(countArr[i] + " ");
}
System.out.println();
}
}
求21位花朵数
最新推荐文章于 2021-02-27 00:39:22 发布