zoukankan      html  css  js  c++  java
  • POJ 1006 Biorhythms (中国剩余定理)

    题意:人生来就有三个生理周期,分别为体力、感情和智力周期,它们的周期长度为23天、28天和33天。每一个周期中有一天是高峰。在高峰这天,

    人会在相应的方 面表现出色。例如,智力周期的高峰,人会思维敏捷,精力容易高度集中。因为三个周期的周长不同,所以通常三个周期的高峰不会落在同一天。

    对于每个人,我们 想知道何时三个高峰落在同一天。对于每个周期,我们会给出从当前年份的第一天开始,到出现高峰的天数(不一定是第一次高峰出现的时间)。

    你的任务是给定一 个从当年第一天开始数的天数,输出从给定时间开始(不包括给定时间)下一次三个高峰落在同一天的时间(距给定时间的天数)。

    例如:给定时间为10,下次出 现三个高峰同天的时间是12,则输出2(注意这里不是3)。

    析:中国剩余定理。假设第 s 天就同时发生,s = a1 + t1 * k1 = a2 + t2 * k2 = a3 + t3 * k3,那么我就很容易得到一个同余方程组。

    也就是 x mod t1 = a1, x mod t2 = a2, x mod t3 = a3。然后就可以用中国剩余定理才做了。

    代码如下:

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include <cstdio>
    #include <string>
    #include <cstdlib>
    #include <cmath>
    #include <iostream>
    #include <cstring>
    #include <set>
    #include <queue>
    #include <algorithm>
    #include <vector>
    #include <map>
    #include <cctype>
    #include <cmath>
    #include <stack>
    #include <ctime>
    #include <cstdlib>
    #define debug puts("+++++")
    //#include <tr1/unordered_map>
    #define freopenr freopen("in.txt", "r", stdin)
    #define freopenw freopen("out.txt", "w", stdout)
    using namespace std;
    //using namespace std :: tr1;
    
    typedef long long LL;
    typedef pair<int, int> P;
    const int INF = 0x3f3f3f3f;
    const double inf = 0x3f3f3f3f3f3f;
    const LL LNF = 0x3f3f3f3f3f3f;
    const double PI = acos(-1.0);
    const double eps = 1e-8;
    const int maxn = 1e6 + 5;
    const LL mod = 1e9 + 7;
    const int N = 1e6 + 5;
    const int dr[] = {-1, 0, 1, 0, 1, 1, -1, -1};
    const int dc[] = {0, 1, 0, -1, 1, -1, 1, -1};
    const char *Hex[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
    inline LL gcd(LL a, LL b){  return b == 0 ? a : gcd(b, a%b); }
    inline int gcd(int a, int b){  return b == 0 ? a : gcd(b, a%b); }
    inline int lcm(int a, int b){  return a * b / gcd(a, b); }
    //int n, m;
    const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    inline int Min(int a, int b){ return a < b ? a : b; }
    inline int Max(int a, int b){ return a > b ? a : b; }
    inline LL Min(LL a, LL b){ return a < b ? a : b; }
    inline LL Max(LL a, LL b){ return a > b ? a : b; }
    //inline bool is_in(int r, int c){
    //    return r >= 0 && r < n && c >= 0 && c < m;
    //}
    
    int exgcd(int a, int b, int &x, int &y){
        if(!b){ x = 1; y = 0;  return a; }
        else{ int r = exgcd(b, a%b, y, x);  y -= x * (a / b);  return r; }
    }
    
    int CRT(int *a, int *m, int n){
        int sum = 1, res = 0;
        for(int i = 0; i < n; ++i)  sum *= m[i];
        for(int i = 0; i < n; ++i){
            int x, y;
            int t = sum / m[i];
            exgcd(t, m[i], x, y);
            res = (res + t * x * a[i]) % sum;
        }
        res = (res + sum + sum - a[3]) % sum;
        return res;
    }
    
    int a[5], m[5];
    
    int main(){
        m[0] = 23;  m[1] = 28; m[2] = 33;
        int kase = 0;
        while(true){
            int res = 0;
            for(int i = 0; i < 4; ++i){
                scanf("%d", a+i);
                res += a[i];
            }
            if(res < 0)  break;
            res = CRT(a, m, 3);
            if(!res)  printf("Case %d: the next triple peak occurs in 21252 days.
    ", ++kase);
            else  printf("Case %d: the next triple peak occurs in %d days.
    ", ++kase, res);
        }
        return 0;
    }
    
  • 相关阅读:
    优先队列
    Problem W UVA 662 二十三 Fast Food
    UVA 607 二十二 Scheduling Lectures
    UVA 590 二十一 Always on the run
    UVA 442 二十 Matrix Chain Multiplication
    UVA 437 十九 The Tower of Babylon
    UVA 10254 十八 The Priest Mathematician
    UVA 10453 十七 Make Palindrome
    UVA 10163 十六 Storage Keepers
    UVA 1252 十五 Twenty Questions
  • 原文地址:https://www.cnblogs.com/dwtfukgv/p/6052251.html
Copyright © 2011-2022 走看看