杨辉三角形//第八届北京师范大学程序设计竞赛决赛

来源:互联网 发布:怎么复制淘宝主图图片 编辑:程序博客网 时间:2024/04/28 04:13

题目链接


杨辉三角形

Time Limit: 1500ms
Memory Limit: 65536KB
64-bit integer IO format: %lld      Java class name: Main
Prev 
Submit Status Statistics Discuss
 Next
Type: 
None
     

      

    LZM同学比较牛,Lsy最近也越来越生猛,他们思路快,代码速度神勇。近期惊闻此二人均要参加校赛,队里决定出些题目卡他们,因为他们的罢工给题目组留下了繁重的负担……(报复报复)
    于是,XsugarX瞄准了LZM不太喜欢看的数学题目以及Lsy猜公式的喜好,奸笑中(^.^)。这个数学问题是个比较古老的问题,有如下图的三角形被称为杨辉三角形:
    1
    1 1
    1 2 1
    1 3 3 1
    1 4 6 4 1
    1 5 10 10 5 1
    我们记第一个1为第0行,往下依次编号。
    其中三角形左右两斜边上的数字均为1,其他位置均为其两肩上的数之和。
    此两牛看到偶数就会觉得复杂,被卡的时间与偶数的个数成正比,XsugarX希望能卡他们的时间越久越好。
    给定任意杨辉三角的行数n,请输出杨辉三角中n中总共有多少偶数。

    Input

      

    一个数n0<=n<=3,000,000)。表示求杨辉三角前n行中偶数的个数。

    Output

      

    一个数R。表示在杨辉三角前n行中共有R个偶数,由于结果可能会很大,请输出R mod 10,000,000的结果。

    Sample Input

    4

    Sample Output

    4

    Source

    第八届北京师范大学程序设计竞赛决赛

    Author

    XsugarX

    Tags 

    Prev 
    Submit Status Statistics Discuss
     Next 

                                                                                                                                                                                                                                                   
    题解:杨辉三角形 分形题目,求杨辉三角形前 n 行的偶数个数。原型是基于一个定理:杨辉三角形的第 n 行中奇数个数等于 2k 个,k 为 n 表示为二进制时 1 的个数。因此,对于 n<=3000000 的数 据范围,可以线性的进行一次扫描,累和打表。 由于统计二进制位,复杂度 O(N)中的 N 会包含一小常数 C,C 为数字的长度。 大多数都是用分形来解决的,当然这也是个很自然的想法,效率会稍微低一 点。另 VIJOS 上有题目的加强版,题目数据 n<=10^50,需要根据上面的定理推倒公式, 然后快速幂+高精解决。 


    附代码

    方法1:

    #include<stdio.h>#include<math.h>#define N 10000000int a[3000001]={0};int gs(int n){    int k=0;    while(n)        {            n=n&(n-1);            k++;        }        return k;}void jg(int n){    int k;        a[2]=1;    a[3]=0;    for(int i=4;i<=n;i++)    {        a[i]=i+1-pow(2,gs(i));      // printf("%d ",a[i]);    }    for(int i=1;i<=n;i++)    {        a[i]=(a[i-1]+a[i])%N;    }}int main(){    int n;    scanf("%d",&n);    jg(n);    printf("%d\n",a[n]%N);}

    方法2:

    #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int MOD=10000000; int dp[3000010]; int sum[3000010]; void pp(){    dp[0]=0;    dp[1]=0;    dp[2]=0;    dp[3]=1;    dp[4]=0;    int x=4;    int i;   for( i=5;i<=3000001;i++)    {    dp[i]=dp[i-x]*2+i-(i-x)*2;//每一行的规律           dp[i]=dp[i]%MOD;            if(i==x*2)                x=x*2;    }    sum[0]=0;    for(i=0;i<=3000000;i++)//加和        sum[i]=(dp[i+1]+sum[i-1])%MOD;}int main(){pp();    int n;    while(~scanf("%d",&n))    {        printf("%d\n",sum[n]);    }}



    0 0
    原创粉丝点击