《算法竞赛入门经典》(刘汝佳)——数学基础(基础)

一:Cantor的数表  

暂时不知道在哪一个oj上有相应的题,所以我只是看看这位高手的博客,就没自己写了。

这个是我抄书上的代码:

#include<stdio.h>
int main()
{
    int n;
    while(scanf("%d", &n) == 1)
    {
        int k = 1, s = 0;
        for(;;)
        {
            s += k;
            if(s >= n)
            {
                printf("%d/%d
", s-n+1,k-s+n);
                break;
            }
            k++;
        }
    }
    return 0;
}
//跑出来证明他的结果不对,因为没考虑斜行的单双数。
View Code

书上利用代数,还可以做的更好(不用循环,直接总结了一个公式),具体的自己买书去看吧~~~

二:因子和阶乘

1:书上的例题解法是先打素数表,再循环判断更新各个素因子的最大下标,然后逐个输出。

暂时没在我知道的oj上找到原题,所以我就看看过了。

  2:poj 1401 Factorial

题目很长,一堆废话,重点就只有几句,汗

总之就是求 阶乘n!末尾0的个数 

 因子5出现的次数一定比2少,因此有多少个5就有多少个10——来自discuss

傻乎乎的暴力会超时:

//For any positive integer N, Z(N) is the number of zeros at the end of the decimal form of number N!. 
//这句话才是题目的重点
//因子5的个数总比2多


//这样子直接模拟超时了
#include<stdio.h>
int main()
{
    int ans,t,n,m;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        ans=0;
        while(n)
        {
            m=n;
            while(m%5==0)
            {
                m=m/5;
                ans++;
            }
            n--;
        }
        printf("%d
",ans);
    }
    return 0;
}
View Code

正解:

//改进一下
//首先要知道 5,10,15,20,25,30,…… 才有因子5

//  100/5=20(相当于把100以内所有参与阶乘的数并且凡是可以整除5的数 都除以5,并记录共整除了20次)
//->20/5=4(同上,还是100以内,被上面那一步骤处理过的数并且仍旧还能整除5的数 都除以5,并再次记录共整除了4次)
//那么20+4=24(上面记录的几次都相加就是100!的值中包含的因子为5的总个数)

//1024/5=204  ->  204/5=40  ->  40/5=8  ->  8/5=1
//那么204+40+8+1=253
#include<stdio.h>
int main()
{
    int ans,t,n;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        ans=0;
        while(n)
        {
            ans+=n/5;
            n=n/5;
        }
        printf("%d
",ans);
    }
    return 0;
}
View Code

 三:果园里的树

四:多少块土地

这两个我都没在我熟知的oj上找到对应的题,所以我就看看过了。

一道又一道,好高兴!
原文地址:https://www.cnblogs.com/laiba2004/p/3599386.html