zoukankan      html  css  js  c++  java
  • 2017.9.24 noip模拟赛 day2—组合数

    简化版题意:

    给定n,m(n<=m),求C(n,m)的末尾有几个0

    输入格式:

    第一行一个整数t,代表数据组数。

    接下来t行,每行两个整数n,m

    输出格式:

    t行,每行一个整数,代表C(n,m)的末尾0的个数。

    样例输入:

    3
    10 1
    11 7
    20 4

    样例输出:

    1
    1
    0

    数据范围:

    1<=m<=n<=1000000,t<=1000

    首先这道题需要知道一个公式:C(n,m)=n!/(n-m)!*m!

    然后10=2*5,也就是说,对于一个数,我们将其因数分解,2和5中较少的数的个数,就是该数末尾0的个数。

    于是对于每一组数据,暴力算出上下两式中2和5的个数,然后上下因为是除的关系,所以可以相互抵消,于是上下的数中2的个数和5的个数中较少的就是0的个数了。

    吐槽一句:题解中说,要用前缀和,但是我并没有写任何与前缀和相关的代码,但是还是A了。

    #include<cstdio>
    void read(int &y)
    {
        y=0;char x=getchar();
        while(x<'0'||x>'9') x=getchar();
        while(x>='0'&&x<='9')
        {
            y=y*10+x-'0';
            x=getchar();
        }
    }
    int solve2(int x)
    {
        int s=0;
        while(x/2!=0)
        {
            s+=x/2;
            x/=2;
        }
        return s;
    }
    int solve5(int x)
    {
        int s=0;
        while(x/5!=0)
        {
            s+=x/5;
            x/=5;
        }
        return s;
    }
    int min(int x,int y)
    {
        return x<y ? x : y;
    }
    int t,m,n;
    int main()
    {
        read(t);
        while(t--)
        {
            read(m),read(n);
            int x=solve2(m)-(solve2(n)+solve2(m-n));
            int y=solve5(m)-(solve5(n)+solve5(m-n));
            printf("%d
    ",min(x,y));
        }
        return 0;
    }
  • 相关阅读:
    【字符串题目】poj 3096 Surprising Strings
    【转载】:【博弈论】博弈的学习和总结
    【博弈论】hihocoder
    转载:SPFA算法学习
    马克思所言:
    【NOIP2013】火柴排队
    【NOIP2013】【P1441】花匠
    【JZOI2002】【BZOJ1477】【P1371】青蛙的约会
    【P1373】奶牛的卧室
    2016.9.16 の 測試
  • 原文地址:https://www.cnblogs.com/zeroform/p/7587619.html
Copyright © 2011-2022 走看看