• [Project Euler] 来做欧拉项目练习题吧: 题目020


                                     [Project Euler] 来做欧拉项目练习题吧: 题目020

                                                       周银辉 

    题目描述:

    n! means n x (n − 1) x ... x 3 x 2 x 1

    For example, 10! = 10 x 9 x ... x 3 x 2 x 1 = 3628800,
    and the sum of the digits in the number 10! is 3 + 6 + 2 + 8 + 8 + 0 + 0 = 27.

    Find the sum of the digits in the number 100! 

    题目分析:

    求100!所得结果的各位数字之和

    做法可以有两种:

    一是做大数乗法,对于Java内置了BigInteger,或者Scheme可以实现无限精度的语言而已,问题就很简单。

    否则自己模拟大数乗法,正如下面的multiply。 

    #include <stdio.h>
    #include <math.h>
    #include <stdlib.h>
    #include <string.h>
    #define BF_SZ 1000 //buffer size
    //将整数转换成字符串,并传出长度, 请手动释放返回值
    //stdlib中的itoa也能完成类似的功能,
    //但stdlib传入的buffer长度未知,一般会设置得比较大,而造成浪费
    char* int_to_str(int n, int* length)
    {
    *length = floor(log10(abs(n!=0?n:1))) + 1;
    char *str = (char*)calloc(sizeof(char)*(*length+1));
    int i = *length-1;
    while(n!=0)
    {
    str[i] = n%10+48;
    n = n/10;
    i--;
    }
    return str;
    }
    //大数乗法,结果放在r中
    void multiply(const char *a,const char *b, char *r)
    {
    int i, j, *t, length_a, length_b, length_t; // t for temp
    length_a = strlen(a);
    length_b = strlen(b);
    length_t = length_a + length_b;
    t=(int*)malloc(sizeof(int)*length_t);
    for(i=0; i<length_t; i++)
    {
    t[i]=0;
    }
    for (i=0; i<length_a; i++)
    {
    for (j=0;j<length_b;j++)
    {
    t[i+j+1] += (a[i]-48)*(b[j]-48);
    }
    }
       // 这里实现进位操作
    for (i=length_t-1; i>=0; i--)      
    {
    if(t[i]>=10)
    {
    t[i-1] += t[i]/10; 
    t[i]   %= 10;
    }
    }
    i=0;
    while(t[i]==0) 
    {
    i++;   // 跳过数前面的0
    }
    for (j=0; i<length_t; i++,j++)
    {
    r[j] = t[i]+48;
    }
    r[j]='\0';
    free(t);
     
    }
    int test(int n, char* buffer, char* temp)
    {
    int i, j, k, a, b, c, p; //p for product
    int len;
    for(i=2; i<=n; i++)
    {
    char *str = int_to_str(i, &len);
    //printf("%s\t", str);
    //做buffer和str的大数乘法
    multiply(buffer, str, buffer);
    free(str);
    }
    return 0;
    }
    int main()
    {
    char* buffer = (char*)malloc(BF_SZ*sizeof(char));
    char* temp   = (char*)malloc(BF_SZ* sizeof(char));
    memset(buffer, '0', BF_SZ);
    buffer[BF_SZ-1] = '1';
    memset(temp, '0', BF_SZ);
    test(100, buffer, temp);
    printf("buffer is %s\n", buffer);
    int i, len=strlen(buffer), count=0;
    for (i=0; i<len; i++) 
    {
    count += buffer[i]-48;
    }
    printf("the count is %d\n", count);
    free(buffer);
    free(temp);
    return 0;

    二是做大数阶乘:
    #include <stdio.h>
    #include <stdlib.h>
    int buffer[1000];
    void multiply(int buffer[],int n,int *length)
    {
    int c=0, i, len=*length;
    for(i=0; i<len; i++)
    {
    buffer[i] = buffer[i]*n + c;
    c         = buffer[i]/10;
    buffer[i]%=10;
    }
    while(c!=0)
    {
    buffer[len++] = c%10;
    c /= 10;
    }
    *length=len;
    }
    main()
    {
    buffer[0]=1;
    int i, n=100, len=1;
    for(i=2; i<=n; i++)
    {
    multiply(buffer, i, &len);
    }
    for(i=len-1; i>=0; i--)
    {
    printf("%d",buffer[i]);
    }
    printf("\n");

    这种模拟大数运算的题目要求细心和耐性,其它便没什么了

  • 相关阅读:
    nginx 配置文件配置
    源码编译php5.4 ./configure参数
    腾讯云Linux VPS新硬盘分区与挂载教程(面板重装不丢失数据)
    十行代码带你量化交易入门
    谱聚类(转)
    随机模拟(MCMC)
    LDA 线性判别分析
    Windows10上安装Keras 和 TensorFlow-GPU
    ASCII 码
    KL距离,Kullback-Leibler Divergence
  • 原文地址:https://www.cnblogs.com/zhouyinhui/p/2023016.html
Copyright © 2020-2023  润新知