https://www.acmicpc.net/problem/1476
1476번: 날짜 계산
준규가 사는 나라는 우리가 사용하는 연도와 다른 방식을 이용한다. 준규가 사는 나라에서는 수 3개를 이용해서 연도를 나타낸다. 각각의 수는 지구, 태양, 그리고 달을 나타낸다. 지구를 나타내는 수를 E, 태양을 나타내는 수를 S, 달을 나타내는 수를 M이라고 했을 때, 이 세 수는 서로 다른 범위를 가진다. (1 ≤ E ≤ 15, 1 ≤ S ≤ 28, 1 ≤ M ≤ 19) 우리가 알고있는 1년은 준규가 살고있는 나라에서는 1 1 1로 나타낼 수 있다. 1
www.acmicpc.net
방법 1 : 나머지 정리
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | import java.util.Scanner; public class Main {     public static void main(String[] args) throws Exception {         // 입력         Scanner sc = new Scanner(System.in);         int E = sc.nextInt();         int S = sc.nextInt();         int M = sc.nextInt();         // 최소공배수 조건을 충족하는 i 출력         // 15*a + E = 28*b + S = 19*c + M = X         for (int i = 1;; i++) {             if (((i - E) % 15 == 0) && ((i - S) % 28 == 0) && ((i - M) % 19 == 0)) {                 System.out.println(i);                 break;             }         }     } } Colored by Color Scripter | 
방법 2 : 최대 범위를 설정하고 거기까지만 계산
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | import java.util.Scanner; public class Main {     public static void main(String[] args) throws Exception {         // 입력         Scanner sc = new Scanner(System.in);         int E = sc.nextInt() - 1;         int S = sc.nextInt() - 1;         int M = sc.nextInt() - 1;         // 문제 조건 만족하는 i + 1 출력         // 15*a + E = 28*b + S = 19*c + M = X         for (int i = 0;; i++) {             if ((i % 15 == E) && (i % 28 == S) && (i % 19 == M)) {                 System.out.println(i + 1);                 break;             }         }     } } Colored by Color Scripter | 
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 28 29 30 31 32 33 | #include <iostream> using namespace std; // 최대범위까지 주어진 조건을 지키는 수 검사 int ESM(int e, int s, int m) {     int MAX = 15 * 28 * 19;     for (int i = 0; i < MAX; i++)     {         if (i % 15 == e && i % 28 == s && i % 19 == m)         {             return i;         }     }     return 0; } int main() {     ios_base::sync_with_stdio(0);     cin.tie(0);     cout.tie(0);     int E, S, M;     cin >> E >> S >> M;     // 수의 범위가 1 <= x <= N 이므로,      // 1씩 빼서 0 <= x - 1 <= N - 1 로 계산     cout << ESM(E - 1, S - 1, M - 1) + 1;     return 0; } Colored by Color Scripter | 
방법 3 : 문제 그대로 구현(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 28 29 30 31 32 33 34 35 36 37 38 39 | #include <iostream> using namespace std; int main() {     ios_base::sync_with_stdio(0);     cin.tie(0);     cout.tie(0);     int E, S, M;     cin >> E >> S >> M;     int i = 1, e = 1, s = 1, m = 1;     while (!(e == E && s == S && m == M))     {         i++;         e++;         s++;         m++;         if (e > 15)         {             e = 1;         }         if (s > 28)         {             s = 1;         }         if (m > 19)         {             m = 1;         }     }     cout << i;     return 0; } Colored by Color Scripter | 
방법 1, 2, 3모두 속도는 같다.
TIP1
for문에 종료조건을 주지 않아도 된다.
TIP2
방법 2에서는 입력값에서 -1 씩 해주어야 한다.
이유는 E, S, M의 값이 0을 제외하기 때문에 그렇다.
예를 들면, E는 1 ≤ E ≤ 15 이므로 1, 2, 3 ... 15, 1, 2, 3 ... 15 를 반복한다.
15를 주기로 반복하게 되므로 i % 15 == E 의 식을 써주면 좋을 것 같은데
i가 30이고 E가 15일 때는 위 식을 만족하지 않는다.
30 % 15 == 15 (X)
따라서 E, S, M의 범위를 1씩 줄여준다.
--> 0≤ (E - 1) ≤ 14, 0 ≤ (S - 1) ≤ 27, 0 ≤ (M - 1) ≤ 18
조건식의 숫자도 1씩 줄여준다.
--> (i - 1) % 15 == (E - 1)
그러면 이제 i가 30, E가 15일 때에도 위 식을 만족할 수 있다.
29 % 15 == 14 (O)
마지막으로 출력값에 다시 +1을 해주면 된다.
길게 썼는데,
결국 2진법은 1, 2가 아니라 0, 1만이 반복된다는 이야기와 동일하다.
간-단!
'Algorithm > BOJ' 카테고리의 다른 글
| [BOJ]6603번: 로또(java, c++) (0) | 2020.01.18 | 
|---|---|
| [BOJ]7568번: 덩치 (0) | 2020.01.11 | 
| [BOJ]3085번: 사탕 게임(java) (0) | 2020.01.05 | 
| [BOJ]2309번: 일곱 난쟁이(java, c++) (0) | 2020.01.04 | 
| [BOJ]2225번: 합분해(java) (0) | 2019.10.19 | 
댓글