• hiho一下 第九十七周 数论六·模线性方程组


    题目1 : 数论六·模线性方程组

    时间限制:10000ms
    单点时限:1000ms
    内存限制:256MB

    描述

    小Ho:今天我听到一个挺有意思的故事!

    小Hi:什么故事啊?

    小Ho:说秦末,刘邦的将军韩信带领1500名士兵经历了一场战斗,战死四百余人。韩信为了清点人数让士兵站成三人一排,多出来两人;站成五人一排,多出来四人;站成七人一排,多出来六人。韩信立刻就知道了剩余人数为1049人。

    小Hi:韩信点兵嘛,这个故事很有名的。

    小Ho:我觉得这里面一定有什么巧妙的计算方法!不然韩信不可能这么快计算出来。

    小Hi:那我们不妨将这个故事的数学模型提取出来看看?

    小Ho:好!

    <小Ho稍微思考了一下>

    小Ho:韩信是为了计算的是士兵的人数,那么我们设这个人数为x。三人成排,五人成排,七人成排,即x mod 3, x mod 5, x mod 7。也就是说我们可以列出一组方程:

    x mod 3 = 2
    x mod 5 = 4
    x mod 7 = 6

    韩信就是根据这个方程组,解出了x的值。

    小Hi:嗯,就是这样!我们将这个方程组推广到一般形式:给定了n组除数m[i]和余数r[i],通过这n组(m[i],r[i])求解一个x,使得x mod m[i] = r[i]。

    小Ho:我怎么感觉这个方程组有固定的解法?

    小Hi:这个方程组被称为模线性方程组。它确实有固定的解决方法。不过在我告诉你解法之前,你不如先自己想想怎么求解如何?

    小Ho:好啊,让我先试试啊!

    提示:模线性方程组

    输入

    第1行:1个正整数, N,2≤N≤1,000。

    第2..N+1行:2个正整数, 第i+1行表示第i组m,r,2≤m≤20,000,000,0≤r<m。

    计算过程中尽量使用64位整型。

    输出

    第1行:1个整数,表示满足要求的最小X,若无解输出-1。答案范围在64位整型内。

    样例输入
    3
    3 2
    5 3
    7 2
    样例输出
    23

    解答:

    一开始没看提示,想的是暴力法,输出满足n个式子的x值,果然提交了,AC不了,超时。赋下超时代码:

     1 #include "iostream"
     2 #define MAX 20000000
     3 
     4 using namespace std;
     5 
     6 typedef long long LL;
     7 
     8 LL m[MAX], r[MAX], n, k;
     9 
    10 int main()
    11 { 
    12     cin>>n;
    13     
    14     if(n<2)
    15         return -1;
    16     
    17     for (int i = 0; i<n; i++)
    18         cin >> m[i] >> r[i];
    19     
    20         for(int i=0;i<MAX;i++){
    21             k = 0;
    22             for (int j = 0; j < n; j++){
    23                 if(i%m[j]==r[j]) 
    24                     k++;
    25             }
    26             if (k == n){
    27                 cout << i << endl;
    28                 system("pause");
    29             }
    30         }    
    31    } 

    期间还出现了个小问题,定义超大数组的时候提示栈溢出。,如果放在main函数里面,栈会overflow。

    因为局部变量存在栈上,一般大小2m,所以会溢出,,,定义成全局变量或static的话,就ok了,大小由系统决定。

    AC代码:

     1 #include "iostream"
     2 #define MAX 20000000
     3 
     4 using namespace std;
     5 
     6 typedef long long LL;
     7 
     8 LL m[MAX], r[MAX], n ;
     9 
    10 LL gcd(LL a, LL b){
    11     if (b == 0)
    12         return a;
    13     return gcd(b, a%b);
    14 }
    15 
    16 void extend_gcd(LL a, LL b, LL &x, LL &y){
    17     if (b == 0){
    18         x = 1;
    19         y = 0;
    20         return ;
    21     }
    22 
    23     LL x1, y1;
    24     extend_gcd(b, a%b, x1, y1);
    25     x = y1;
    26     y = x1 - (a / b)*y1;
    27 }
    28 
    29 LL Solve()
    30 {
    31     LL M = m[1], R = r[1], d, k1, k2, c;
    32     for (int i = 2; i <= n; i++)
    33     {
    34         d = gcd(M, m[i]);
    35         c = r[i] - R;
    36         if (c % d)
    37             return -1;                          // 无解的情况
    38         extend_gcd(M / d, m[i] / d, k1, k2);
    39         k1 = (c / d*k1) % (m[i] / d);           // 计算x = m[1] * k[1] + r[1]
    40         R = R + k1*M;                           // 求解lcm(M, m[i])
    41         M = M / d*m[i];                         // 求解合并后的新R,同时让R最小
    42         R %= M;
    43     }
    44     if (R < 0)
    45         R = R + M;
    46     return R;
    47 }
    48 
    49 int main()
    50 {
    51     cin >> n;
    52 
    53     for (int i = 1; i <= n; i++)
    54         cin >> m[i] >> r[i];
    55     cout << Solve() << endl;
    56 
    57     system("pause");
    58 }
  • 相关阅读:
    【SAS NOTE】OUTPUT
    【SAS NOTES】_NULL_
    【SAS NOTE】sas 9.2 安装
    【SAS NOTE】FREQ
    纯数学教程 Page 203 例XLI (1)
    纯数学教程 Page 203 例XLI (3)
    纯数学教程 Page 203 例XLI (2)
    Prove Cauchy's inequality by induction
    纯数学教程 Page 325 例LXVIII (15) 调和级数发散
    纯数学教程 Page 325 例LXVIII (15) 调和级数发散
  • 原文地址:https://www.cnblogs.com/SeekHit/p/5477392.html
Copyright © 2020-2023  润新知