ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 백준 6064 (카잉 달력) c++
    백준 문제 2022. 8. 7. 14:25
    728x90

    문제

     

    6064번: 카잉 달력

    입력 데이터는 표준 입력을 사용한다. 입력은 T개의 테스트 데이터로 구성된다. 입력의 첫 번째 줄에는 입력 데이터의 수를 나타내는 정수 T가 주어진다. 각 테스트 데이터는 한 줄로 구성된다.

    www.acmicpc.net

    m과 n이 주어지고 x와 y가 주어지면 <x, y>가 몇번째로 이루어지는지 구하는 문제입니다.

    만약 <x, y>가 안되면 -1을 출력하면 됩니다.

    <1, 1> 부터 시작하며 x' n을 넘어가면 다시 x'가 1로 되고 y도 마찬가지 입니다.

    예를 들어 m과 n이 10, 12 라면

    <1, 1> 부터 시작해 <10, 10> 까지 가고 <11, 11>은 x'가 m을 넘어가 되므로 <10, 10> 다음에는 <1, 11> 이 됩니다.

    마찬가지로 <2, 12>가 되고 다음 순서는 <3, 13> 이 되어야 하지만 y'가 n을 넘어가게 되므로 <3, 12>가 됩니다.

     

    <10, 12> 는 60번째 에서 마지막이 되고 끝이 납니다.

     

    단순히 <x, y>가 될 때 까지 반복문을 돌리게 되면 시간초과가 나게 됩니다.

     

    따라서 새로운 방법을 구해야 합니다.

    요점은 바로 x를 기준으로 맞춘다는 것입니다. 즉, x를 기준으로 하면 y만 신경 써주면 됩니다.

    예를 들어 m과 n이 <10 ,12> 이고 x와 y가 <3, 9> 라면

    x가 3이므로 3일 경우에만 y를 판별해 주면 됩니다.

    y는 n까지 증가하므로 나머지 연산을 통해 판별해주면 됩니다. 

    먼저 처음에 x = 3일 경우

    x = 3

    y = 3 % 12 = 3

     

    다음에 x가 3일 경우에는 x는 m만큼 증가 하므로 m을 더해주면 됩니다.

    x = (3 + 10) = 3

    y = (3 + 10) % 12 = 1

     

    x = ( 3 + 10 + 10) = 3

    y = (3 + 10 + 10) % 12 = 11

     

    x = (3 + 10 + 10 + 10) = 3

    y = (3 + 10 + 10 + 10) % 12 = 9

    따라서 (3 +10 +10 +10)번의 연산을 했을 때 <3, ,9> 가 나오므로 정답은 (3 + 10 + 10 +10) = 33이 됩니다.

     

    하지만 만약 답이 될 수 없는 경우도 있습니다. 그렇게 되면 계속 해서 반복문이 실행이 되고 결국 시간초과가

    나오게 됩니다.

    문제에서의 힌트는 m과 n이 <10, 12>의 경우에는 최종 해가 <10, 12> 가 되어 60번째에서 끝이 나게 됩니다.

    즉, m과 n의 최소공배수에서 끝이 납니다. 

    만약 최소공배수를 넘어가게 되면 해당 x와 y는 답이 될 수 없습니다.

    다음과 같이 gcd를 먼저 구해주면 lcm(최소공배수)를 구할 수 있습니다.

    lcm으로 나온 수를 lim에 넣어주고 lim까지 반복문을 돌려 줍니다.

    i가 lim을 넘어가게 되면 정답이 없는 것이므로 -1을 출력해줍니다.


    전체 코드 입니다.

    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
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <string>
    #include <stack>
    #include <queue>
    #include <deque>
    #include <cmath>
    #include <map>
    #include <set>
    #include <tuple>
    #define MAX 2100000000
    #define inf LONG_MAX
    #define big(a, b) a > b ? a : b
    using namespace std;
    using ll = long long;
    using ull = unsigned long long;
    int gcd(int a, int b);
    int lcm(int a, int b);
    int main() {
        ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
        int t;
        cin >> t;
        while (t--) {
            int m, n, x, y, i;
            cin >> m >> n >> x >> y;
            int lim = lcm(m, n);
            for (i = x; i <= lim; i += m) {
                int temp = (i % n == 0) ? n : i % n;
     
                if (temp == y) {
                    cout << i << '\n';
                    break;
                }
            }
            if (i > lim)
                cout << -1 << '\n';
        }
     
     
     
        return 0;
    }
    int gcd(int a, int b) {
        if (!b)
            return a;
        return gcd(b, a % b);
    }
    int lcm(int a, int b) {
        return a * b / gcd(a, b);
    }
    cs

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

    백준 5430 (AC) C++  (0) 2022.08.10
    백준 1107 (리모컨) c++  (0) 2022.08.09
    백준 1541 (잃어버린 괄호) c++  (0) 2022.08.01
    백준 17626 (Four Squares) c++  (0) 2022.07.30
    백준 9375 (패션완 신해빈) c++  (0) 2022.07.29
Designed by Tistory.