본문 바로가기

백준

[JAVA] 백준 6064번: 카잉 달력

 


문제

  • 각 년도를 <x:y> 형태로 표현하고, 첫 해를 <1:1>, 두 번째 해를 <2:2>로 표현한다.
  • M과 N이 주어질 때, 다음 해를 <x':y'> 라고 한다면,
    • x < M 이면 x` = x + 1, 그렇지 않으면 x' = 1
    • y < N 이면 y' = y + 1, 그렇지 않으면 y' = 1
  • 방식으로 다음 해의 년도를 구한다.
  • M, N, x, y가 주어질 때, <x:y>가 몇 번째 해를 나타내는지 구하는 문제.

 

아이디어

  • 규칙성을 찾아 해결한다.
  • M=6, N=9가 주어진 경우, 년도를 나열해보자.
  • (1) 1:1, (2) 2:2, (3) 3:3, (4) 4:4, (5) 5:5, (6) 6:6
    (7) 1:7, (8) 2:8, (9) 3:9, (10) 4:1, (11) 5:2, (12) 6:3
    (13) 1:4, (14) 2:5, (15) 3:6, (16) 4:7, (17) 5:8, (18) 6:9
    (19) 1:1 ...
  • 총 M과 N의 최소공배수 만큼의 년도를 표시할 수 있으며,
    x:y가 해당 해를 M, N으로 나눈 나머지와 동일하다는 것을 알 수 있다.
    • (8) 2:8의 경우,
    • 8을 M(6)으로 나눈 나머지인 2, 
    • 8을 N(9)으로 나눈 나머지인 8로 구성된다.
  • 즉, x, y가 몇 번째 해(answer)를 나타내는지를 알기 위해서는, answer % M == x, answer % N == y 인 answer를 구하면 된다.
  • 하지만, x, y가 3, 9 혹은 6, 9와 같이 M, N으로 나누었을 때, 나누어 떨어지면 문제가 발생하므로, 모든 x와 y에서 1을 뺀 값을 기준으로 해답을 구한 뒤, 1을 더해준다.

 

풀이

import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder();

        int T = Integer.parseInt(br.readLine());

        for(int t=0; t<T; t++) {
            StringTokenizer st = new StringTokenizer(br.readLine());

            int M = Integer.parseInt(st.nextToken());
            int N = Integer.parseInt(st.nextToken());
            int x = Integer.parseInt(st.nextToken());
            int y = Integer.parseInt(st.nextToken());
            
            // 최소공배수를 구하기 위해 최대공약수 구하기
            int a = N;
            int b = M;
            int tmp = 0;
            while (b != 0) {
                tmp = b;
                b = a % b;
                a = tmp;
            }
            
            // 최소공배수
            int lcm = M * N / a;
            int answer = -1;
            
            // 나머지가 0인 경우를 대비해 나머지가 x-1, y-1인 경우를 탐색
            // x-1 부터 시작해 M씩 더해가며 해답을 도출
            for (int i = x-1; i < lcm + 1; i += M) {
                // (i%M) == x-1 이며(이미 충족), (i%N) == y-1인 i 탐색
                if (i % N == y-1) {
                    answer = i;
                    break;
                }
            }
            // 표현이 가능한 해면 + 1 해서 출력
            // 아니면 -1 출력
            sb.append(answer+1 !=0 ? answer+1 : -1).append('\n');
        }
        System.out.println(sb);

    }
}

 

채점 결과

6064번 채점 결과

기타

  • 규칙을 찾고 흥분한 나머지, 나누어 떨어지는 경우를 계산 못해 틀렸다... 더 주의하자.

 

문제 링크

'백준' 카테고리의 다른 글

[JAVA] 백준 11403번: 경로 찾기  (0) 2024.08.27
[JAVA] 백준 11286번: 절댓값 힙  (0) 2024.08.26
[JAVA] 백준 5525번: IOIOI  (0) 2024.08.25
[JAVA] 백준 2667번: 단지번호붙이기  (0) 2024.08.23
[JAVA] 백준 2178번: 미로 탐색  (0) 2024.08.22