문제
https://www.acmicpc.net/problem/9020
문제 요약
골드바흐의 추측이란 유명한 정수론의 미해결 문제이다.
2보다 큰 모든 짝수는 두 소수의 합으로 나타낼 수 있다는 것이다.
이러한 수를 골드바흐 수라고 한다.
또, 짝수를 두 소수의 합으로 나타내는 표현을 골드바흐 파티션이라고 한다.
2보다 큰 짝수 n이 주어졌을 때, n의 골드바흐 파티션을 출력한다.
+ 만약 가능한 n의 골드바흐 파티션이 여러 가지인 경우, 두 소수의 차이가 가장 작은 것을 출력한다.
코드
#include <iostream>
#include <vector>
using namespace std;
int T;
// arr[i]가 true라면, i는 소수
bool arr[10010];
vector<int> v;
void gold(int n) {
int left = 0;
int right = v.size() - 1;
int res_left = 0;
int res_right = 0;
// 투포인터
while (left <= right) {
int sum_lf = v[left] + v[right];
if (sum_lf == n) {
res_left = v[left];
res_right = v[right];
left++;
right--;
}
else if (sum_lf < n) {
left++;
}
else {
right--;
}
}
cout << res_left << " " << res_right << "\n";
}
int main() {
// 입출력 단축 코드
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
for (int i = 0; i <= 10000; i++) {
arr[i] = true;
}
// 에라토스테네스의 체 알고리즘
for (int i = 2; i * i <= 10000; i++) {
// 소수가 이미 아니라면, 건너뛰기
if (!arr[i]) continue;
int j = 2;
while (i * j <= 10000) {
arr[i * j] = false;
j += 1;
}
}
for (int i = 0; i < 10000; i++) {
if (arr[i]) v.push_back(i);
}
cin >> T;
while (T--) {
int n;
cin >> n;
gold(n);
}
return 0;
}
코드 설명
1. 에라토스테네스의 체 알고리즘을 활요하여 10000까지 수 중 소수들의 리스트를 벡터 v에 저장한다.
2. 입력 받은 수 n에 대해 투포인터 알고리즘을 통해 골드바흐 파티션을 출력한다.
투포인터 알고리즘에서 두 포인터가 가리키는 소수의 합이 n이어도, 차이가 작은 파티션이 존재할 수 있으므로, left, right 포인터를 한 칸씩 움직여 계속 탐색한다.
고찰
오랜만에 에라토스테네스의 체 알고리즘을 구현하려 하니, 까먹어서 시간이 좀 걸렸다.
복습하자!
'Algorithm Problems > 투 포인터' 카테고리의 다른 글
[백준/C++] 2018번: 수들의 합 5 (1) | 2024.03.27 |
---|---|
[백준/C++] 15565번: 귀여운 라이언 (0) | 2024.03.26 |
[백준/C++] 7453번: 합이 0인 네 정수 (0) | 2024.03.20 |
[백준/Python] 2470번: 두 용액 (1) | 2023.11.08 |
[백준/Python] 1644번: 소수의 연속합 (2) | 2023.11.07 |