문제
![](https://www.acmicpc.net/favicon-16x16.png)
![](http://onlinejudgeimages.s3-ap-northeast-1.amazonaws.com/images/boj-og-1200.png)
최근에 ICPC 탐사대는 남아메리카의 잉카 제국이 놀라운 문명을 지닌 카잉 제국을 토대로 하여 세워졌다는 사실을 발견했다. 카잉 제국의 백성들은 특이한 달력을 사용한 것으로 알려져 있다. 그들은 M과 N보다 작거나 같은 두 개의 자연수 x, y를 가지고 각 년도를 <x:y>와 같은 형식으로 표현하였다.
그들은 이 세상의 시초에 해당하는 첫 번째 해를 <1:1>로 표현하고, 두 번째 해를 <2:2>로 표현하였다. <x:y>의 다음 해를 표현한 것을 <x':y'>이라고 하자. 만일 x < M 이면 x' = x + 1이고, 그렇지 않으면 x' = 1이다. 같은 방식으로 만일 y < N이면 y' = y + 1이고, 그렇지 않으면 y' = 1이다. <M:N>은 그들 달력의 마지막 해로서, 이 해에 세상의 종말이 도래한다는 예언이 전해 온다.
예를 들어, M = 10 이고 N = 12라고 하자. 첫 번째 해는 <1:1>로 표현되고, 11번째 해는 <1:11>로 표현된다. <3:1>은 13번째 해를 나타내고, <10:12>는 마지막인 60번째 해를 나타낸다.
네 개의 정수 M, N, x와 y가 주어질 때, <M:N>이 카잉 달력의 마지막 해라고 하면 <x:y>는 몇 번째 해를 나타내는지 구하는 프로그램을 작성하라.
입력
- 입력 데이터는 표준 입력을 사용한다.
- 입력은 T개의 테스트 데이터로 구성된다.
- 입력의 첫 번째 줄에는 입력 데이터의 수를 나타내는 정수 T가 주어진다.
- 각 테스트 데이터는 한 줄로 구성된다.
- 각 줄에는 네 개의 정수 M, N, x와 y가 주어진다. (1 ≤ M, N ≤ 40,000, 1 ≤ x ≤ M, 1 ≤ y ≤ N)
- 여기서 <M:N>은 카잉 달력의 마지막 해를 나타낸다.
출력
- 출력은 표준 출력을 사용한다.
- 각 테스트 데이터에 대해, 정수 k를 한 줄에 출력한다.
- 여기서 k는 <x:y>가 k번째 해를 나타내는 것을 의미한다.
- 만일 <x:y>에 의해 표현되는 해가 없다면, 즉, <x:y>가 유효하지 않은 표현이면, -1을 출력한다.
풀이
잉카 달력의 기준과 확인하고자 하는 해를 입력하면 몇번째 해인지 찾는 문제다.
문제는 복잡해 보이는데 결국 양쪽다 1씩 증가하면서 최댓값에 도달하면 1로 돌아가는 순환 로직을 갖는다. 이 로직을 알고 나니 문제 해결이 훨씬 용이했다.
각각 증가하면서 순환하게 되므로 마지막 해는 자연스럽게 M과 N의 최소공배수가 될 것이다.
이제 확인하고자 하는 수가 들어왔을떄 로직은 작은 수를 기준으로 일치하는 값을 찾고 작은 수만큼 증가시키며 큰수도 일치하는지 확인했다.
확인하는 수를 작은 값 기준으로 시작해 증가시키며 확인하고 최소공배수를 넘어가면 찾지 못한것이므로 -1
을 반환했다.
- 많은 실패가 있었지만 수학적인 접근이 틀려 의미가 없으므로 이 글에 남기지 않는다.
답
from math import gcd
from sys import stdin
input = stdin.readline
def acin(m, n, x, y):
if m > n:
m, n, x, y = n, m, y, x
tmp = y
while tmp < (m * n // gcd(m, n) + 1):
t = tmp % m if tmp % m != 0 else m
if t == x:
return tmp
tmp += n
return -1
if __name__ == "__main__":
T = int(input())
for _ in range(T):
M, N, X, Y = map(int, input().split())
res = acin(M, N, X, Y)
print(res)
⭐일단 던져서 답인지 확인하는 못된 버릇 고쳐야합니다. 고갱님.. ⭐
❗스스로 테스트케이스 만드는 버릇을 들입시다❗
Uploaded by Notion2Tistory v1.1.0