※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 14905번 문제인 소수 4개의 합이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/14905
14905번: 소수 4개의 합
모든 자연수를 4개의 소수의 합으로 나타낼 수 있을까? 이 물음에 대한 답은 '8 이상의 모든 자연수에 대해 그렇다'이지만, 데이빗은 그 사실을 알지 못했다. 데이빗은 프로그램을 돌려 4개의 소
www.acmicpc.net
모든 소수는 2 이상이므로 주어지는 수가 8보다 작다면 조건을 만족하는 네 수를 찾는 것은 항상 불가능함을 알 수 있다. 아래부터는 주어지는 수가 8 이상이라 가정하자.
prime gap
위 지식을 이용하면, 먼저 주어지는 수와 6 이상 차이가 나는 가장 큰 소수를 찾고 주어진 수에서 찾은 수를 뺀 수를 세 소수의 합으로 구성하는 것으로 문제를 해결할 수 있음을 알 수 있다. 한편, 골드바흐의 추측(Goldbach's Conjecture)이 충분히 작은 범위의 양의 정수에 대하여 성립함을 이용하면, 남은 수가 짝수가 되게끔 2 또는 3을 골라 뺀 다음 조건을 만족하는 남은 두 소수를 찾아 남은 문제를 해결할 수 있음을 관찰할 수 있다.
prime gap에 대한 자세한 내용은 링크를 참고하자.
아래는 제출한 소스코드이다.
#include <iostream>
#include <vector>
using namespace std;
bool sieve[10001];
vector<int> P;
void sieveinit() {
sieve[0] = sieve[1] = 1;
for (int i = 2; i < 10001; i++) {
if (sieve[i]) continue;
P.emplace_back(i);
for (int j = i * i; j < 10001; j += i) sieve[j] = 1;
}
}
int N;
void solve() {
if (N < 8) {
cout << "Impossible.\n";
return;
}
for (int k = N - 6; k > 0; k--) {
bool chk = 1;
for (auto &p : P) {
if (k % p) continue;
if (k != p) chk = 0;
break;
}
if (chk) {
cout << k << ' ';
N -= k;
break;
}
}
if (N & 1) N -= 3, cout << 3 << ' ';
else N -= 2, cout << 2 << ' ';
for (auto &p : P) {
if (sieve[N - p]) continue;
cout << p << ' ' << N - p << '\n';
return;
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
sieveinit();
while (cin >> N) solve();
}
'BOJ' 카테고리의 다른 글
[BOJ 19576 // C++] 약수 (1) | 2024.03.22 |
---|---|
[BOJ 13343 // C++] Block Game (0) | 2024.03.21 |
[BOJ 11692 // C++] 시그마 함수 (3) | 2024.03.19 |
[BOJ 5462 // C++] POI (0) | 2024.03.18 |
[BOJ 17254 // C++] 키보드 이벤트 (2) | 2024.03.17 |