题意
现在我们有杨辉三角
我们要求前n行的杨辉三角的偶数的个数之和
题目的n的值很大 , n <= 150
思路
分两步走,主要在于先找到规律,然后n的值很大,用java的大数解决。
那么首先我们要知道 杨辉三角前n项个数为 n ∗ ( n + 1 ) 2 \frac{n*(n + 1)}{2} 2n∗(n+1)
1.每行奇数的个数一定为2k(k为自然数)
2.当行数恰为2k(k为自然数)时,奇数个数为2k,偶数个数为零
3.当行数恰为2k(k为自然数)时,奇数个数和恰为3(k-1)
一个数可以分解成若干个2k 的和,所以我们先对数进行分解,例如:
2333 = 2048+256+16+8+4+1
通过暴力,我们可以找出2333的所有奇数个数为190985
那么,我们找出如下数字
行数 所有奇数个数
2048 177147
256 6561
16 81
8 27
4 9
1 1
我们可以发现:
177147×1 + 6561×2 + 81×4 + 27×8 + 9×16 + 1×32 恰好等于 190985!
代码
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
static BigInteger one = BigInteger.ONE;
static BigInteger zero = BigInteger.ZERO;
static BigInteger n;
static BigInteger [] a = new BigInteger[171];
static BigInteger [] b = new BigInteger[171];
public static void init_b()
{
b[0] = one;
for(int i = 1; i <= 170; i++)
b[i] = b[i - 1].multiply(BigInteger.valueOf(3));
}
public static void init_a(BigInteger n){
BigInteger x = one;
x = x.shiftLeft(170);
BigInteger t = new BigInteger("170");
a[0] = zero;
while (n != zero)
{
if(n.compareTo(x) > 0 || n.equals(x))
{
n = n.subtract(x);
a[0] = a[0].add(one);
a[a[0].intValue()] = t;
}
x = x.divide(BigInteger.valueOf(2));
t = t.subtract(one);
}
}
public static void main(String[] args){
Scanner cin = new Scanner(System.in);
while(cin.hasNext())
{
n = cin.nextBigInteger();
n = n.add(one);
init_b();
init_a(n);
BigInteger ans;
ans = zero;
for(int i = 1; i <= a[0].intValue(); i++)
{
BigInteger tep = b[a[i].intValue()];
BigInteger x = one;
tep = tep.multiply(x.shiftLeft(i-1));
ans = ans.add(tep);
}
BigInteger sum = n.multiply(n.add(one));
sum = sum.divide(BigInteger.valueOf(2));
ans= sum.subtract(ans);
System.out.println(ans);
}
}
}
参考来源
https://blog.csdn.net/ZCY19990813/article/details/98101197