【同余方程组】POJ1006 生理周期

同余方程组:

  先来看一道题目:有物不知其数,三三数之剩二;五五数之剩三;七七数之剩二。问物几何?  然后我们可以做如下变换,设x为所求的数。

   x%3=2              x = a1(%m1)  ①
   x%5=3  ===>  x = a2(%m2)  ②
   x%7=2              x = a3(%m3)

  根据前面两式可以得到

    x = a1+m1y1     (1)
   x = a2+m2y2

  两式相减得到  m1y1 - m2y2 = a2 - a1  这是一个线性不定方程,可解出y1  ---> linearEquation(m1,-m2,a2-a1)   带回(1),得特解x0 = a1+m1*y1 --> 得到通解表达式 x =x0 + k*lcm(m1,m2) 得一个新方程 x = x0 (mod lcm(m1,m2))

  代码:

/**
 *
 * @param a 余数组成的数组
 * @param m 模组成的数组
 * @return
 * @throws Exception
 */
public static long linearEquationGroup(Long[] a, Long[] m) throws Exception {
  int len = a.length;
  if (len == 0 && a[0] == 0)
    return m[0];

  for (int i = 1; i < len; i++) {
    // 这里往前看是两个方程
    long a2_a1 = a[i] - a[i - 1];
    long d = linearEquation(m[i - 1], -m[i], a2_a1);
    // 现在的x是y1,用y1求得一个特解
    long x0 = a[i - 1] + m[i - 1] * x;
    long lcm = m[i - 1] * m[i] / d;
    a[i] = (x0 % lcm + lcm) % lcm;// x0变成正数
    m[i] = lcm;
  }
  // 合并完之后,只有一个方程 : x = a[len-1] (% m[len-1])
  //long d = linearEquation(1, m[len-1], a[len-1]);
  return a[len - 1] % m[len - 1];
}

题目:POJ1006 生理周期

  

  

  代码:

 1 import java.util.ArrayList;
 2 import java.util.List;
 3 import java.util.Scanner;
 4
 5 public class POJ1006 {
 6
 7     public static void main(String[] args) throws Exception {
 8         Scanner scanner = new Scanner(System.in);
 9         int t = 1;
10         List<Long[]> aList = new ArrayList<Long[]>();
11         List<Long> dList = new ArrayList<Long>();
12         while(scanner.hasNext()){
13             Long []a = {scanner.nextLong(),scanner.nextLong(),scanner.nextLong()};
14             Long d = scanner.nextLong();
15             if (a[0]==-1&&a[1]==-1&&a[2]==-1&&d==-1) {
16                 break;
17             }else {
18                 aList.add(a);
19                 dList.add(d);
20             }
21         }
22         for (int i = 0; i < aList.size(); i++) {
23             Long[] a = aList.get(i);
24             long d = dList.get(i);
25             Long[] m = { (long) 23, (long) 28, (long) 33 };
26             long res = MyGcd.linearEquationGroup(a, m);
27             while (res <= d) {
28                 res += 21252;
29             }
30             System.out.println("Case " + (t++) + ": the next triple peak occurs in " + (res - d) + " days.");
31         }
32     }
33
34     private static class MyGcd {
35         static long x;
36         static long y;
37
38         /**
39          *
40          * @param a 余数组成的数组
41          * @param m 模组成的数组
42          * @return
43          * @throws Exception
44          */
45         public static long linearEquationGroup(Long[] a, Long[] m) throws Exception {
46             int len = a.length;
47             if (len == 0 && a[0] == 0)
48                 return m[0];
49
50             for (int i = 1; i < len; i++) {
51                 // 这里往前看是两个方程
52                 long a2_a1 = a[i] - a[i - 1];
53                 long d = linearEquation(m[i - 1], -m[i], a2_a1);
54                 // 现在的x是y1,用y1求得一个特解
55                 long x0 = a[i - 1] + m[i - 1] * x;
56                 long lcm = m[i - 1] * m[i] / d;
57                 a[i] = (x0 % lcm + lcm) % lcm;// x0变成正数
58                 m[i] = lcm;
59             }
60             // 合并完之后,只有一个方程 : x = a[len-1] (% m[len-1])
61             //long d = linearEquation(1, m[len-1], a[len-1]);
62             return a[len - 1] % m[len - 1];
63         }
64
65         public static long inverseElement(long a, long mo) throws Exception {
66
67             long d = linearEquation(a, mo, 1);
68             x = (x % mo + mo) % mo;
69             return d;
70         }
71
72         public static long linearEquation(long a, long b, long m) throws Exception {
73             long d = ext_gcd(a, b);
74             // m不是gcd(a,b)的倍数,这个方程无解
75             if (m % d != 0)
76                 throw new Exception("无解");
77             long n = m / d;// 约一下,考虑m是d的倍数
78             x *= n;
79             y *= n;
80             return d;
81         }
82
83         public static long ext_gcd(long a, long b) {
84
85             if (b == 0) {
86                 x = 1;
87                 y = 0;
88                 return a;
89             }
90             long res = ext_gcd(b, a % b);
91             long x1 = x;// 备份x
92             x = y;// 更新x
93             y = x1 - a / b * y;// 更新y
94             return res;
95         }
96
97     }
98
99 }

  结果:

    

原文地址:https://www.cnblogs.com/xiaoyh/p/10336238.html

时间: 2024-10-03 00:45:10

【同余方程组】POJ1006 生理周期的相关文章

poj1006生理周期(中国剩余定理)

1 /* 2 中国剩余定理可以描述为: 3 若某数x分别被d1..….dn除得的余数为r1.r2.….rn,则可表示为下式: 4 x=R1r1+R2r2+…+Rnrn+RD 5 其中R1是d2.d3.….dn的公倍数,而且被d1除,余数为1:(称为R1相对于d1的数论倒数) 6 R1 . 7 R2 . 8 … . 9 Rn是d1.d2.….dn-1的公倍数,而且被dn除,余数为1: 10 D是d1.d2.….的最小公倍数: 11 R是任意整数(代表倍数),可根据实际需要决定: 12 且d1..…

【数论】【中国剩余定理】poj1006 生理周期

CRT用于求解一元线性同余方程组(模数互质),实际上模数不互质我们也可以解决,在之前的某篇文章里提过.如下 http://www.cnblogs.com/autsky-jadek/p/6596010.html #include<cstdio> using namespace std; typedef long long ll; ll m[4],a[4],D,ans; void exgcd(ll a,ll b,ll &d,ll &x,ll &y){ if(!b){ d=a

POJ1006 生理周期

本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/转载请注明出处,侵权必究,保留最终解释权! Description 人生来就有三个生理周期,分别为体力.感情和智力周期,它们的周期长度为23天.28天和33天.每一个周期中有一天是高峰.在高峰这天,人会在相应的方面表现出色.例如,智力周期的高峰,人会思维敏捷,精力容易高度集中.因为三个周期的周长不同

poj1006生理周期(中国剩余定理)

生理周期 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 139224   Accepted: 44687 Description 人生来就有三个生理周期,分别为体力.感情和智力周期,它们的周期长度为23天.28天和33天.每一个周期中有一天是高峰.在高峰这天,人会在相应的方面表现出色.例如,智力周期的高峰,人会思维敏捷,精力容易高度集中.因为三个周期的周长不同,所以通常三个周期的高峰不会落在同一天.对于每个人,我们想知道

生理周期 (poj 1006) 题解

[问题描述] 人生来就有三个生理周期,分别为体力.感情和智力周期,它们的周期长度为23天.28天和33天.每一个周期中有一天是高峰.在高峰这天,人会在相应的方面表现出色.例如,智力周期的高峰,人会思维敏捷,精力容易高度集中.因为三个周期的周长不同,所以通常三个周期的高峰不会落在同一天.对于每个人,我们想知道何时三个高峰落在同一天.对于每个周期,我们会给出从当前年份的第一天开始,到出现高峰的天数(不一定是第一次高峰出现的时间).你的任务是给定一个从当年第一天开始数的天数,输出从给定时间开始(不包括

生理周期 枚举算法问题

趁着寒假抓紧自学C++..... 生理周期问题是比较简单的算法问题,运用到了  枚举  的思想. 人生来就有三个生理周期,分别为体力.感情和智力周期,它们的周期长度为 23 天. 28 天和33 天.每一个周期中有一天是高峰.在高峰这天,人会在相应的方面表现出色.例 如,智力周期的高峰,人会思维敏捷,精力容易高度集中.因为三个周期的周长不同,所以 通常三个周期的高峰不会落在同一天.对于每个人,我们想知道何时三个高峰落在同一天. 对于每个周期,我们会给出从当前年份的第一天开始,到出现高峰的天数(不

生理周期(c++实现)

描述:人生来就有三个生理周期,分别为体力.感情和智力周期,它们的周期长度为23 天. 28 天和33 天.每一个周期中有一天是高峰.在高峰这天,人会在相应的方面表现出色.例如,智力周期的高峰,人会思维敏捷,精力容易高度集中.因为三个周期的周长不同,所以通常三个周期的高峰不会落在同一天.对于每个人,我们想知道何时三个高峰落在同一天.对于每个周期,我们会给出从当前年份的第一天开始,到出现高峰的天数(不一定是第一次高峰出现的时间).你的任务是给定一个从当年第一天开始数的天数,输出从给定时间开始(不包括

poj——1006 生理周期

生理周期 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 138291   Accepted: 44300 Description 人生来就有三个生理周期,分别为体力.感情和智力周期,它们的周期长度为23天.28天和33天.每一个周期中有一天是高峰.在高峰这天,人会在相应的方面表现出色.例如,智力周期的高峰,人会思维敏捷,精力容易高度集中.因为三个周期的周长不同,所以通常三个周期的高峰不会落在同一天.对于每个人,我们想知道

1007: 生理周期

1007: 生理周期 时间限制: 10 Sec  内存限制: 128 MB提交: 418  解决: 233[提交][状态][讨论版] 题目描述 人生来就有三个生理周期,分别为体力.感情和智力周期,它们的周期长度为23 天. 28 天和33 天.每一个周期中有一天是高峰.在高峰这天,人会在相应的方面表现出色.例如,智力周期的高峰,人会思维敏捷,精力容易高度集中.因为三个周期的周长不同,所以通常三个周期的高峰不会落在同一天.对于每个人,我们想知道何时三个高峰落在同一天.对于每个周期,我们会给出从当前