작성일 :

문제 링크

9182번 - Biorhythms

설명

육체 23일, 감정 28일, 지성 33일의 세 주기가 있습니다. 각 주기별로 올해 시작일부터의 피크 일과 오늘 날짜가 주어집니다.

오늘을 포함하지 않고, 세 주기의 피크가 동시에 오는 다음 날까지 남은 일수를 구하는 문제입니다.


접근법

먼저, 세 주기의 최소공배수는 21252일입니다. 이 값이 전체 사이클이 됩니다.

다음으로, 중국인의 나머지 정리를 이용해 세 주기의 공통 피크일을 구합니다. 미리 계산된 계수를 사용하면, 각 피크일에 5544, 14421, 1288을 곱해 더한 후 21252로 나눈 나머지가 공통 피크일이 됩니다.

이후, 공통 피크일에서 오늘 날짜를 뺍니다. 결과가 0 이하이면 다음 사이클로 넘어가야 하므로 21252를 더합니다.


Code

C#

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using System;

namespace Solution {
  class Program {
    static void Main(string[] args) {
      var cycle = 21252;
      var caseNo = 1;
      while (true) {
        var tokens = Console.ReadLine()!.Split();
        var p = int.Parse(tokens[0]);
        var e = int.Parse(tokens[1]);
        var i = int.Parse(tokens[2]);
        var d = int.Parse(tokens[3]);
        if (p == -1 && e == -1 && i == -1 && d == -1)
          break;

        var x = (5544 * p + 14421 * e + 1288 * i) % cycle;
        var ans = x - d;
        if (ans <= 0)
          ans += cycle;

        Console.WriteLine($"Case {caseNo}: the next triple peak occurs in {ans} days.");
        caseNo++;
      }
    }
  }
}

C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <bits/stdc++.h>
using namespace std;

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);

  int cycle = 21252;
  int p, e, i, d, tc = 1;
  while (cin >> p >> e >> i >> d) {
    if (p == -1 && e == -1 && i == -1 && d == -1)
      break;

    int x = (5544 * p + 14421 * e + 1288 * i) % cycle;
    int ans = x - d;
    if (ans <= 0)
      ans += cycle;

    cout << "Case " << tc << ": the next triple peak occurs in " << ans << " days.\n";
    tc++;
  }

  return 0;
}