백준 2824번 최대공약수
<백준 2824번 최대공약수 - 마포 코딩박>
사용한 알고리즘: 에라토스테네스의 체
문제에서 N개 수의 곱 A 와 M개 수의 곱 B 의 gcd 를 묻고 있습니다.
문제풀이는 다음과 같습니다.
(1) 수는 최대 10^9이 주어지므로 에라토스테스의 체로 40000까지의 소수들을 구해줍니다. ( 어떤 수 A 는 root(A) 이상의 소수로는 나눠지지 않습니다. )
(2) map을 사용하여 N개의 수가 입력될 때 각 수들의 소인수 분해 값을 저장합니다. M개의 수가 입력될 때 이를 반복합니다. (단, 따로 저장)
(3) 구하고자 하는 값을 ans (long long)로 놓고, A의 수에대해 저장한 소인수 분해 값들을 보면서, B의 수에 대한 소인수 분해와 겹치는 만큼 ans에 곱해줍니다.
(4) 과정 (3)을 할 때, ans 가 10^9이 넘어가는지 체크해주고, 넘어간다면 이를 10^9으로 modulo 취해줍니다.
(5) 과정 (4)에서 10^9이 넘어간다고 체크된 경우 출력시 9자리까지만 출력하라는 조건에 유의해서 출력합니다. 제 경우에는 width 함수를 사용하였고, 남는 자리는 fill 함수로 0을 채워줬습니다.
사용한 알고리즘: 에라토스테네스의 체
문제에서 N개 수의 곱 A 와 M개 수의 곱 B 의 gcd 를 묻고 있습니다.
문제풀이는 다음과 같습니다.
(1) 수는 최대 10^9이 주어지므로 에라토스테스의 체로 40000까지의 소수들을 구해줍니다. ( 어떤 수 A 는 root(A) 이상의 소수로는 나눠지지 않습니다. )
(2) map을 사용하여 N개의 수가 입력될 때 각 수들의 소인수 분해 값을 저장합니다. M개의 수가 입력될 때 이를 반복합니다. (단, 따로 저장)
(3) 구하고자 하는 값을 ans (long long)로 놓고, A의 수에대해 저장한 소인수 분해 값들을 보면서, B의 수에 대한 소인수 분해와 겹치는 만큼 ans에 곱해줍니다.
(4) 과정 (3)을 할 때, ans 가 10^9이 넘어가는지 체크해주고, 넘어간다면 이를 10^9으로 modulo 취해줍니다.
(5) 과정 (4)에서 10^9이 넘어간다고 체크된 경우 출력시 9자리까지만 출력하라는 조건에 유의해서 출력합니다. 제 경우에는 width 함수를 사용하였고, 남는 자리는 fill 함수로 0을 채워줬습니다.
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; | |
#define ll long long | |
const int MOD = 1000000000; | |
// 문제에서 요구하는 출력형식을 맞춰주고, 답이 너무 커져 터지는걸 유의. | |
int N, M; | |
map<int, int> A, B; | |
vector<int> Prime; | |
bool visited[40000]; | |
void MakeA(int a){ | |
for(auto now: Prime){ | |
if(a%now==0){ | |
A[now]++; | |
MakeA(a/now); | |
return; | |
} | |
} | |
if(a!=1) A[a]++; | |
} | |
void MakeB(int a){ | |
for(auto now: Prime){ | |
if(a%now==0){ | |
B[now]++; | |
MakeB(a/now); | |
return; | |
} | |
} | |
if(a!=1) B[a]++; | |
} | |
int main(){ios_base::sync_with_stdio(false); cout.tie(NULL); cin.tie(NULL); | |
for (int i = 2; i < 40000; ++i){ | |
if(visited[i]) continue; | |
Prime.push_back(i); | |
for (int j = 2*i; j < 40000; j+=i) visited[j] = true; | |
} | |
bool Over = false; | |
cin >> N; | |
for (int i = 0; i < N; ++i){ | |
int num; | |
cin >> num; | |
MakeA(num); | |
} | |
cin >> M; | |
for (int i = 0; i < M; ++i){ | |
int num; | |
cin >> num; | |
MakeB(num); | |
} | |
ll ans = 1LL; | |
for(auto iter: A){ | |
int now = iter.first; | |
if(!B.count(now)) continue; | |
int cnt = min(A[now],B[now]); | |
while(cnt--){ | |
ans*=now; | |
// ans 가 MOD 보다 큰값인지 아닌지 체크! (출력형식이 달라짐) | |
if(ans>MOD){ | |
Over=true; | |
ans%=MOD; | |
} | |
} | |
} | |
if(Over){ | |
ans%=MOD; | |
cout.width(9); | |
cout.fill('0'); | |
cout << ans << '\n'; | |
} | |
else cout << ans << '\n'; | |
return 0; | |
} |
댓글
댓글 쓰기
긴 글 읽어주셔서 감사합니다.
궁금한게 있으시다면 댓글 달아주세요!