I Count the Even Integers (ICPC Asia HongKong 2017)杨辉三角

8 篇文章 4 订阅
3 篇文章 0 订阅

题目链接 

input
4
8
12
output
4
16
42

 题意:输出杨辉三角前n行所有偶数的个数。从两个1那一行开始计数。数据量超大,10的50次方,所以用JAVA处理大数。

首先输出一下杨辉三角找规律

#include <algorithm>
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
typedef long long ll;
int main()
{
    ll n,i,j,e,k;
    cin>>n;
    for(i=2;i<=n;i++)
    {
        k=1;e=0;
        for(j=1;j<=n-i;j++)
        cout<<" ";

        for(j=1;j<=i;j++)
        {
            if(e==0)
                cout<<k%2;
            else
                cout<<" "<<k%2;
            k=k*(i-j)/j;
            e++;
        }
        cout<<endl;
    }
    return 0;
}

会出现一个非常漂亮的图案:

即:

因为数据量超大,需要JAVA大数处理,只给出c++的代码,等下学期学了JAVA在更新。

通过暴力会发现:

杨辉三角前 n 项 个数为  n*(n+1)/2

1.每行奇数个数一定为2^k(k为自然数)

2.当行数恰为2^k(k为自然数)时,奇数个数为2^k,偶数个数为零

3.当行数恰为2^k(k为自然数)时,奇数个数和恰为3^(k-1)

一个数 可以分解成 若干个 2^k   之和

所以 对数进行分解。 

例如:2333 = 2048+256+16+8+4+1

通过暴力程序,我们可以找出2333的所有奇数个数为190985

那么,我们找出如下数字


    行数               所有奇数个数
    2048(……)          177147(……)
    256(2的8次方)      6561(3的8次方)
    16(2的4次方)       81(3的4次方)
    8(2的3次方)        27(3的3次方)
    4(2的2次方)        9(3的2次方)
    1                 1

我们可以发现:

177147×1 + 6561×2 + 81×4 + 27×8 + 9×16 + 1×32 恰好等于 190985! 

注意:这个只是适合数据量小的,在本题中不适合,放在这方便找规律。

#include <algorithm>
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
typedef long long ll;
ll a[200],b[200];
int main()
{
    ll n,i;

    b[0]=1;
    for(i=1;i<=50;i++)
        b[i]=b[i-1]*3;
    while(cin>>n)
    {
        n+=1;
        ll sum=(n+1)*n/2;
        ll e=0;
        while(n)
        {
            a[e++]=n%2;
            n/=2;
        }
        ll p=1,ans=0;
        for(i=e-1;i>=0;i--)
        {
            if(a[i]==1)
            {
                ans+=b[i]*p;
                p*=2;
            }
        }
        cout<<sum-ans<<endl;
    }
    return 0;
}

 

AC代码:(代码原博客)

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);
            }
           // System.out.println(ans);
            BigInteger sum= n.multiply(n.add(one));
            sum=sum.divide(BigInteger.valueOf(2));
            //System.out.println(sum);
            ans= sum.subtract(ans);
            System.out.println(ans);

        }
      }
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值