백준 9613. GCD 합
알고리즘 기초 문제 중 수학1 연습 문제
1. 간단 설명
양의 정수 N이 주어졌을 때, 가능한 모든 쌍의 GCD의 합을 구하는 문제
각 테스트케이스마다
수의 개수 n과, n개의 수가 주어지는데
이 n개의 수의 가능한 모든 쌍의 GCD의 합을 구하는 문제
예시
예를들어
1
2
1
4 10 20 30 40
이 주어진 경우
TC1 은 4개의 수 {10, 20, 30, 40}이 주어진다
이 수들로 만들 수 있는 GCD는
10, 20 => 10 10, 30 => 10 10, 40 => 10 20, 30 => 10 20, 40 => 20 30, 40 => 10
이므로 합은 70이 된다
2. 문제 분석
주의사항
- 테스트 케이스 개수가 최대 100개이고, 각 테케에서 수의 개수는 100개다
- 입력으로 주어지는 수들은 1,000,000을 넘지 않는다. 최대 999,999!
필요 변수들
- 테스트 케이스 개수
int T
(1<= t <=100) - 수의 개수
int n
(1 < n ≤ 100) - 주어지는 수들을 저장할 벡터.
vector<int> v
각 수는 100만을 넘지 않으므로 int형 가능 - gcd의 합들을 저장할 변수
long long int res
- TC
100 999999 999999 ... 999999
의 gcd의 합은100c2 * 999999
이므로,
약 49억이므로 INT형은 Overflow 발생
- TC
- 조합을 위한 변수들
- algorithm 헤더의 next_permutation을 사용해도 되지만 직접 구현해봄
- 선택된 배열 원소를 저장할
int arr[MAX]
- 이미 선택된 배열 체크를 위한
bool check[MAX]
알고리즘
1
2
3
4
5
6
7
8
1. TC입력 받기
2. 각 TC별 다음 수행
2-1. 기존에 사용했던 res와 벡터 초기화
2-2. n과 n개의 원소 입력받기
2-3. n개의 원소 중, 2개를 조합
2-3-1. 조합을 이용해 두개의 원소를 선택
2-3-2. 2개의 원소가 선택됬다면, 두 수의 GCD를 구해 res에 더한다
2-4. 최종 결과값 res를 출력
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
53
#include <iostream>
#include <vector>
#include <numeric>
#define MAX 101
using namespace std;
int n;
long long int res = 0;
vector<int> v;
int arr[MAX];
bool check[MAX];
void combination(int level, int start) {
if (level == 2) {
// 고른 두개의 수의 gcd를 res에 더한다
res += gcd(arr[0], arr[1]);
return;
}
for (int i = start; i < n; i++) {
if (check[i] == true) continue;
check[i] = true;
arr[level] = v[i];
combination(level + 1, i);
check[i] = false;
}
}
int main() {
freopen_s(new FILE*, "input.txt", "r", stdin);
int T; cin >> T;
while (T--) {
res = 0;
v.clear();
cin >> n;
for (int i = 0; i < n; i++) {
int tmp; cin >> tmp;
v.push_back(tmp);
}
// 2개 조합
combination(0, 0);
cout << res << '\n';
}
return 0;
}
배운점
첫 제출에서 오버플로우 생각 안하고 제출했다가 한번 틀렸다
제출하기 전에 꼭 최대값 TC 생각해보고 제출할 것!
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.