백준 1476번 날짜 계산
< 백준 1476번 날짜 계산 - 마포 코딩박 >
사용한 알고리즘: 수학 ( 확장 유클리드, 중국인의 나머지 정리 )
주기가 15, 28, 19 인 E, S, M의 값을 각각 주고, 몇년이 흘렀는지 계산하는 문제였습니다.
사실 중국인의 나머지 정리와 확장 유클리드에 대한 지식이 없다면 해결하기 힘든 문제였던 것 같습니다.
문제풀이는 다음과 같습니다.
(1) (수학)
중국인의 나머지 정리 개념은 스킵하고 이를 통한 풀이만 쓰겠습니다.
15, 28, 19 는 서로 서로소입니다. 입력 E , S, M 이 주어지고, N = 15*28*19, N1=N/15, N2=N/28, N3=N/19 라 합시다.
M1*N1=1 (mod 15) , M2*N2=1 (mod 28) , M3*N3=1 (mod 19) 인 M1,M2,M3 를 구하면 구하고자 하는 답 ans = (E*N1*M1+S*N2*M2+M*M3*N3)%N 입니다.
(이때 ans=0 인 경우 0년 후는 답이 아니니 ans = N 입니다.)
확장 유클리드와 중국인의 마지막 정리에 대해서는 ries님(강산 님)의 네이버 블로그에 자세히 나와있으니 원하시는 분은 들어가보시는 것을 추천드립니다.
사용한 알고리즘: 수학 ( 확장 유클리드, 중국인의 나머지 정리 )
주기가 15, 28, 19 인 E, S, M의 값을 각각 주고, 몇년이 흘렀는지 계산하는 문제였습니다.
사실 중국인의 나머지 정리와 확장 유클리드에 대한 지식이 없다면 해결하기 힘든 문제였던 것 같습니다.
문제풀이는 다음과 같습니다.
(1) (수학)
중국인의 나머지 정리 개념은 스킵하고 이를 통한 풀이만 쓰겠습니다.
15, 28, 19 는 서로 서로소입니다. 입력 E , S, M 이 주어지고, N = 15*28*19, N1=N/15, N2=N/28, N3=N/19 라 합시다.
M1*N1=1 (mod 15) , M2*N2=1 (mod 28) , M3*N3=1 (mod 19) 인 M1,M2,M3 를 구하면 구하고자 하는 답 ans = (E*N1*M1+S*N2*M2+M*M3*N3)%N 입니다.
(이때 ans=0 인 경우 0년 후는 답이 아니니 ans = N 입니다.)
확장 유클리드와 중국인의 마지막 정리에 대해서는 ries님(강산 님)의 네이버 블로그에 자세히 나와있으니 원하시는 분은 들어가보시는 것을 추천드립니다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <bits/stdc++.h> | |
using namespace std; | |
typedef pair<int, int> pii; | |
// 중국인의 나머지 정리 | |
// ax = 1 (mod b) 인 x 구하기 , 확장 유클리드 | |
pii ext_gcd(int a, int b){ | |
if(b){ | |
pii tmp = ext_gcd(b,a%b); | |
return pii(tmp.second, tmp.first - (a/b)*tmp.second); | |
} | |
else return pii(1,0); | |
} | |
int mod_inv(int a, int tt){ | |
return (ext_gcd(a,tt).first + tt)%tt; | |
} | |
// ~15, ~28, ~19 | |
int E, S, M; | |
int main(){ios_base::sync_with_stdio(false); cout.tie(NULL); cin.tie(NULL); | |
cin >> E >> S >> M; | |
int N = 15*28*19; | |
int N_1 = N/15; | |
int N_2 = N/28; | |
int N_3 = N/19; | |
// ( M_1 * N-1 ) + ( m_1 * 15 ) = 1 | |
// 즉 M_1 * N_1 = 1 ( mod 15 ) 를 구해야 한다. | |
int M_1 = mod_inv(N_1,15); | |
int M_2 = mod_inv(N_2,28); | |
int M_3 = mod_inv(N_3,19); | |
long long ans = E*N_1*M_1 + S*N_2*M_2 + M*N_3*M_3; | |
ans%=N; | |
while(ans<=0) ans+=N; | |
cout << ans << '\n'; | |
return 0; | |
} |
댓글
댓글 쓰기
긴 글 읽어주셔서 감사합니다.
궁금한게 있으시다면 댓글 달아주세요!