21919 소수 최소공배수
여러 수들이 주어졌을 때,
소수를 찾고, 그 소수들의 최소 공배수를 구하는 문제
https://www.acmicpc.net/problem/21919
1. 문제
간단 설명
위에 설명한 그대로임
길이가 N인 수열 A에서 소수들을 골라 최소공배수를 구할 것
2. 문제 분석
필요변수
수열의 길이 N
(1<= N <= 10,000)
수열의 원소 A_i가 공백으로 주어짐
A_i 는 2 <= A_i <= 1,000,000 의 범위를 가진다
수열을 저장할 벡터 v
답은 2^63 미만인 입력만 주어진다
주의점
- 답은 2^63 미만이다. 즉, int형으로는 처리 불가
- 중복인 원소가 주어질 수도 있다
알고리즘
1
2
3
4
5
6
7
8
1. N 입력받기
2. N번 입력받으면서, 그 수가 소수인지 먼저 판별 후, 소수라면 v에 넣는다
- 소수 판별은 에라체를 이용해도 가능하지만, N과 A가 크지 않아 직접 계산함
3. 원소의 중복을 제거
- cpp의 unique 함수 사용 전에는 꼭 정렬해주어야함
4. 소수인 원소들의 최소공배수를 출력한다
- 보통 a * b / gcd(a, b)로 최소 공배수를 구하지만, 소수는 자기 자신 외에는 나눠지는 수가 없으므로
그냥 두 수를 곱하는게 최소 공배수가 된다.
소수 판별에 관련 내용은 이 글 참조 1990 소수인 펠린드롬
3. 소스코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>
#include <algorithm>
#include <vector>
#include <math.h>
#include <numeric>
using namespace std;
// n이 소수인지 판별하는 함수
bool IsPrime(int n) {
// 수학적 증명에 의해 2~sqrt(N)까지만 나눠도 소수인지 판별 가능함
for (int i = 2; i <= sqrt(n); i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
int main() {
freopen_s(new FILE*, "input.txt", "r", stdin);
int N;
vector<int> v;
cin >> N;
// 1. 소수인 수만 벡터에 삽입
for (int i = 0; i < N; i++) {
int tmp; cin >> tmp;
if (IsPrime(tmp))
v.push_back(tmp);
}
// 소수가 없는경우
if (v.empty()) {
cout << -1;
return 0;
}
// cpp에선 중복 원소 제거하기전, 정렬 필요
sort(v.begin(), v.end());
unique(v.begin(), v.end());
// 2. 최소 공배수 구하기
unsigned long long res = 1;
for (int e : v) {
res = lcm(res, e);
}
cout << res;
return 0;
}
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.