오늘의 알고리즘

[C++] 백준 6064 카잉달력

하늘하늘 . 2022. 9. 15. 23:50
#include <iostream>
 
int GCD(int iFirst, int iSecond)
{
    while (iSecond)
    {
        int iRemain = iFirst % iSecond;
        iFirst = iSecond;
        iSecond = iRemain;
    }
 
    return iFirst;
}
 
int LCM(int iFirst, int iSecond)
{
    return iFirst * iSecond / GCD(iFirst, iSecond);
}
 
int main()
{
    int T = 0;
    int M = 0;
    int N = 0;
    int x = 0;
    int y = 0;
    std::cin >> T;
 
    for (int i = 0; i < T; ++i)
    {
        std::cin >> M >> N >> x >> y;
 
        int iMax = LCM(M, N);
 
        for (; x <= iMax; x += M)
        {
            if ((x - 1) % N + 1 == y || x > iMax)
            {
                break;
            }
        }
 
        if (x > iMax)
        {
            std::cout << -1 << "\n";
        }
 
        else
        {
            std::cout << x << "\n";
        }
    }
 
    return 0;
}

방법을 못찾겠어서 하나하나 계산해보니까 최소공배수에 수렵했습니다.

이전에 배웠던 나머지 수(서로 나눠서 남는 나머지가 0이 될 때까지 나누는 방법)를 이용해서 최대공약수를 구하고

본래의 수 두 개를 곱해 최소공배수를 구했습니다.

그 후 최소공배수를 넘었는데도 정했던 수가 아니라면 break 합니다.

(x - 1) % M + 1을 하는 이유는 x는 M값이 나오면 나머지가 0이 나오기 때문에 - 1,

나머지가 1부터 M까지 나와야 하기 때문에 + 1 해줬습니다.