본문 바로가기
알고리즘 문제풀이/백준

[백준 6064] 카잉 달력

by m2162003 2020. 12. 18.

www.acmicpc.net/problem/6064

 

6064번: 카잉 달력

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

www.acmicpc.net

수학 문제이다. 어렵게 접근하면 한없이 어려워지지만 x를 고정하고 y값을 변화시킨다고 생각하면 쉽다.

-1이 나오는 경우는 <m:n>에 해당하는 마지막 k번째 해를 넘어갈 때인데 k는 m과 n의 최소 공배수이다.

 

++ 최소 공배수 구하기

a와 b의 최소 공배수는 a * b / gcd(a,b)이다.

gcd는 유클리드 호제법을 사용하여 구해주면 된다.

정리하는 김에 코드를 간단히 적어본다.

int gcd(int a, int b)
{
	int r;
    while(b){
    	r = a % b;
        a = b;
        b = r;
    }
    return a;
}

 

 

다시 문제로 돌아와서 k를 구해보자.

k = x로 초기화한다. k는 y값을 대신하며 리턴값이다.

k는 m씩 증가하는데 최대 n을 넘을 수 없으므로 k %= n일 것이다.

 

하지만 k % n == y하면 틀린다. 왜냐면 n이 y와 같을 경우 k가 n의 배수이면 무조건 0이 나오기 때문이다. 

13 11 1 11의 경우 답이 66이지만 66번째에서

22 % 11 = 0 (11이 나와야 함) 

으로 계산하여 66번째에 break를 나오지 못할 것이다.

 

따라서 (k-1) % n + 1 == y를 해줘야 한다.

 

k % n = y  <=>  (k-1) % n + 1 = y인데 그 이유는

www.acmicpc.net/board/view/54865 여기 댓글에 잘 설명되어 있다.

 

(k-1) % n + 1을 해주면 k가 n의 배수이더라도 결과값이 0이되지 않고 n-1이 되어 +1을 했을 때 n이 된다

 

#include <stdio.h>
#include <algorithm>
using namespace std;

int t;
int m, n, x, y;

int LCM(int a, int b)
{
  int lcm = a * b;
  int r;
  while (b)
  {
    r = a % b;
    a = b;
    b = r;
  }

  return lcm / a;
}
int main(void)
{
  scanf("%d", &t);

  while (t--)
  {
    scanf("%d%d%d%d", &m, &n, &x, &y);
    int k = x;

    int lcm = LCM(m, n);
    while (1)
    {
      if (k > lcm)
      {
        k = -1;
        break;
      }
      if ((k - 1) % n + 1 == y)
      {
        break;
      }
      k += m;
    }
    printf("%d\n", k);
  }
  return 0;
}

 

'알고리즘 문제풀이 > 백준' 카테고리의 다른 글

[백준 17141] 연구소 2  (0) 2020.12.19
[백준 1978] 소수 찾기  (0) 2020.12.18
[백준 15684] 사다리 조작  (0) 2020.12.17
[백준 14503] 로봇 청소기  (0) 2020.12.17
[백준 14499] 주사위 굴리기  (0) 2020.12.17

댓글