zoukankan      html  css  js  c++  java
  • I00022 孙子定理

    问题:有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二。问物几何?答曰:二十三。

    这个问题用现在的话说就是,有一个数,用3除余2,用5除余3,用7除余2,问该数是多少?

    该问题最早可见于中国南北朝时期(公元5世纪)的数学著作《孙子算经》卷下第二十六题。是一个数学问题,更准确地说是一个数论问题,也是一个经典的数论问题。

    孙子定理是中国古代求解一次同余式组的方法,是数论四大定理之一,国际上称为中国剩余定理。该题是孙子定理中的典型问题。

    现在是计算机时代,绝大多数问题都用计算来解决,即编写程序计算解决。用数论算法来解,应该说是正解。参见:《模乘逆元与孙子定理》一文。

    如果只学过计算机语言而不懂数论,是不是就没有办法来解这个问题了?答案显然是否定的。解决这个问题,穷举法的应该是一个办法,总是能够算出结果来的。

    然而,计算过程不同,速度有快慢之别。这里给出的程序,从模(除数)最大开始穷举试探,步伐大必然步数少。根据本题题意,7为最大除数,所以优先使用除数为7的条件;除7余2,其解必然是2+7k(k=0,1,2,,3,......)的形式,k从0开始逐一增大穷举试算,把满足条件的解找出来。

    用孙子定理或者说用数论的方法解决问题,对于模(除数)是有要求的。要求模(除数)必须是两辆互素的。而这个程序对此没有要求。

    对于标准的孙子定理问题,算出的解是23。其实,该问题的通解是23+105k(k=0,1,2,,3,......),105=3*5*7。

    还需要主意的一点是,编写程序需要有通用性,才能做到一劳永逸。

    程序如下:

    /* 孙子定理(中国剩余定理):穷举法 */
    
    #include <stdio.h>
    
    int crt(int m[], int r[], int n)
    {
        int x, flag, i, temp;
    
        // step1 找出最大的模(除数),放在m[0],相应的余数也放在r[0]
        for(i=1; i<n; i++) {
            if(m[i] > m[0]) {
                temp = m[i];
                m[i] = m[0];
                m[0] = temp;
    
                temp = r[i];
                r[i] = r[0];
                r[0] = temp;
            }
        }
    
        // step2 试探法求满足各个模(除数)条件的数
        x = r[0];
        flag = 0;
        while(!flag) {
            flag = 1;
            for(i=1; i<n; i++)
                if(x % m[i] != r[i]) {
                    flag = 0;
                    break;
                }
            if(flag)
                break;
            x += m[0];
        }
    
        return x;
    }
    
    int main(void)
    {
        int m[] = {3, 5, 7};
        int r[] = {2, 3, 2};
        printf("%d
    ", crt(m, r, sizeof(m)/sizeof(int)));
    
        int m2[] = {103, 107, 109};
        int r2[] = {44, 63, 21};
        printf("%d
    ", crt(m2, r2, sizeof(m2)/sizeof(int)));
    
        int m3[] = {30, 51, 34, 103};
        int r3[] = {29, 2, 19, 30};
        printf("%d
    ", crt(m3, r3, sizeof(m3)/sizeof(int)));
    
        return 0;
    }

    3组数据的计算结果如下:

    23
    2310
    2399

  • 相关阅读:
    abstract关键字
    final关键字
    Vue使用枚举类型实现HTML下拉框
    第八节 pandas读取和保存文件
    第七节 pandas新建数据框的两种方式
    第六节 numpy的常用属性和方法
    第五节 numpy的简单使用
    第三节 matplotlib绘制直方图
    第三节 matplotlib绘制条形图
    第二节 matplotlib绘制散点图
  • 原文地址:https://www.cnblogs.com/tigerisland/p/7564777.html
Copyright © 2011-2022 走看看