• 中国剩余定理 poj1006 模板


    题目链接:http://poj.org/problem?id=1006

    题意:每个人的体力,情感,智力周期分别为23,28和33天。一个周期内有一天为峰值,在这一天,人在对应的方面(体力,情感或智力)表现最好。通常这三个周期的峰值不会是同一天。现在给出三个日期,分别对应于体力,情感,智力出现峰值的日期。然后再给出一个起始日期,要求从这一天开始,算出最少再过多少天后三个峰值同时出现。

    分析:中国剩余定理的板子题

    23,28,33满足两两互质,故直接套板子即可

    先上模板:

    //n个方程:x=a[i](mod m[i]) (0<=i<n)
    LL china(int n, LL *a, LL *m){
        LL M = 1, ret = 0;
        for(int i = 0; i < n; i ++) M *= m[i];
        for(int i = 0; i < n; i ++){
            LL w = M / m[i];
            ret = (ret + w * inv(w, m[i]) * a[i]) % M;
        }
        return (ret + M) % M;
    }

    然后代码

    #include<cstdio>
    typedef long long LL;
    const int N = 100000 + 5;
    void ex_gcd(LL a, LL b, LL &x, LL &y, LL &d){
        if (!b) {d = a, x = 1, y = 0;}
        else{
            ex_gcd(b, a % b, y, x, d);
            y -= x * (a / b);
        }
    }
    LL inv(LL t, LL p){//如果不存在,返回-1 
        LL d, x, y;
        ex_gcd(t, p, x, y, d);
        return d == 1 ? (x % p + p) % p : -1;
    }
    LL china(int n, LL *a, LL *m){//中国剩余定理 
        LL M = 1, ret = 0;
        for(int i = 0; i < n; i ++) M *= m[i];
        for(int i = 0; i < n; i ++){
            LL w = M / m[i];
            ret = (ret + w * inv(w, m[i]) * a[i]) % M;
        }
        return (ret + M) % M;
    }
    int main(){
        LL p[3], r[3], d, ans, MOD = 21252;
        int cas = 0;
        p[0] = 23; p[1] = 28; p[2] = 33;
        while(~scanf("%I64d%I64d%I64d%I64d", &r[0], &r[1], &r[2], &d) && (~r[0] || ~r[1] || ~r[2] || ~d)){
            ans = ((china(3, r, p) - d) % MOD + MOD) % MOD;
            printf("Case %d: the next triple peak occurs in %I64d days.
    ", ++cas, ans ? ans : 21252);
        }
        
    }
  • 相关阅读:
    mui的相关知识
    4. 本地的json格式调用方法
    DOM树节点的相关知识
    3.函数引用中“值传参”与“引用传参”的区别
    一,数组的创建 数组的遍历
    重载<<
    SendMessage、PostMessage、PeekMessage、GetMessage、PreTreslateMessage等
    TranslateMessage
    怎样在整个类中恒定常量
    格式化输出
  • 原文地址:https://www.cnblogs.com/qingjiuling/p/11386331.html
Copyright © 2020-2023  润新知