poj 1006(中国剩余定理+模板题)
Posted qingfengdahui
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj 1006(中国剩余定理+模板题)相关的知识,希望对你有一定的参考价值。
题意:人自出生起就有体力,情感和智力三个生理周期,分别为23,28和33天。一个周期内有一天为峰值,在这一天,人在对应的方面(体力,情感或智力)表现最好。通常这三个周期的峰值不会是同一天。现在给出三个日期,分别对应于体力,情感,智力出现峰值的日期。然后再给出一个起始日期,要求从这一天开始,算出最少再过多少天后三个峰值同时出现。
设第x天同时出现,则x%23=p%23,x%28=i%28...(等于p,i也是可以的,计算中会mod),然后用x-d即可,因为x可能小于d,所以加上23*28*33再对这个数取模。
1 #include<iostream> 2 #include<string.h> 3 #include<string> 4 #include<sstream> 5 #include<vector> 6 #include<deque> 7 #include<map> 8 #include<algorithm> 9 #include<iomanip> 10 #include<math.h> 11 #include<set> 12 using namespace std; 13 14 typedef long long ll; 15 typedef unsigned long long ull; 16 const int mod = 1000000007; 17 18 //扩展欧几里得求逆元 19 ll exgcd(ll &x,ll &y,ll a,ll b) 20 { 21 if (b == 0) 22 { 23 x = 1; 24 y = 0; 25 return a; 26 } 27 ll r = exgcd(x, y, b, a%b); 28 ll temp = x; 29 x = y; 30 y = temp - a / b * y; 31 return r; 32 } 33 34 ll inv(ll a,ll b) 35 { 36 ll x, y; 37 ll g = exgcd(x, y, a, b); 38 if (g == 1) 39 { 40 return (x%b + b) % b; 41 } 42 else 43 return -1; 44 } 45 46 ll china(ll *n, ll *m,ll len) 47 { 48 ll M = 1; 49 ll res = 0; 50 for (int i = 0; i < len; i++) 51 M = M * m[i]; 52 for (int i = 0; i < len; i++) 53 { 54 ll t = M / m[i]; 55 res = (res + t * inv(t, m[i])*n[i]) % M; 56 } 57 return (res+M)%M; //防止res为负数(不太懂) 58 } 59 60 int main() 61 { 62 int cas = 1; 63 int p, e, i, d; 64 ll m[3] = {23,28,33}, n[3]; 65 while (cin >> e >> i >> d>>p && p != -1) 66 { 67 n[0] = e % 23; 68 n[1] = i % 28; 69 n[2] = d % 33; 70 ll ans = (china(n, m, 3)-p+21252)%21252; 71 ans = ans ? ans : 21252; 72 cout << "Case " << cas++ << ": the next triple peak occurs in " << ans << " days." << endl; 73 } 74 return 0; 75 }
以上是关于poj 1006(中国剩余定理+模板题)的主要内容,如果未能解决你的问题,请参考以下文章
poj 1006Biorhythms(数论--中国剩余定理 模版题){附中国剩余定理 }