백준/수학
백준 6588 c++ "골드바흐의 추측" -PlusUltraCode-
PlusUltraCode
2025. 5. 29. 11:05
https://www.acmicpc.net/problem/6588
[필자 사고]
에라토스테네스의 채 알고리즘을 알고 있으면 해당 문제를 쉽게 해결할 수 있다.
초기에 해당 소수들을 판정한 뒤
주어진 숫자들을 3, 5 ,7 등 소수 홀수부터 점검하여 diff 가 소수라고 한다면 문제 해결이다.
아래는 자세한 코드 해설이다.
[코드 해설]
Input_Init()
- 소수 판별을 위해 isPrime 벡터를 크기 MAX+1로 true로 초기화한 후, 에라토스테네스의 체 알고리즘을 사용해 소수가 아닌 수를 false로 설정함.
- 0과 1은 소수가 아니므로 false로 설정함.
- 2부터 sqrt(MAX)까지 순회하면서, 해당 수가 소수이면 그 배수들을 모두 소수가 아닌 것으로 표시함.
Print(int num, int leftSosu, int rightSosu)
- num = leftSosu + rightSosu 형식으로 결과를 출력함.
- 골드바흐의 추측에서 제시한 두 소수의 합을 출력하는 역할임.
Game_Start(int num)
- num을 두 개의 소수의 합으로 나타낼 수 있는지를 검증하는 함수.
- 3부터 MAX까지 홀수 중에서 소수만 검사하며 반복함.
- 현재 소수 i를 기준으로 num - i가 소수인지 확인.
- 조건을 만족하면 두 소수의 합으로 num을 표현하고 종료.
- 만약 해당 조건을 만족하는 두 소수를 못 찾으면 "Goldbach's conjecture is wrong."를 출력하고 종료함.
main()
- 빠른 입출력을 위해 ios::sync_with_stdio(false)와 cin.tie(0), cout.tie(0) 설정.
- Input_Init()을 호출하여 소수 판별 배열을 초기화.
- 무한 루프를 통해 사용자로부터 수를 계속 입력받음.
- 입력이 0이면 루프를 종료.
- 입력받은 수에 대해 Game_Start() 함수를 호출하여 골드바흐의 추측을 검증함.
[소스 코드]
#include <iostream>
#include <vector>
#include <cmath>
#define MAX 1000000
using namespace std;
vector<bool> isPrime;
void Input_Init() {
isPrime.resize(MAX + 1,true);
isPrime[0] = false;
isPrime[1] = false;
for (int i = 2; i <= sqrt(MAX); i++) {
if (isPrime[i] == false) continue;
for (int k = i * i; k <= MAX; k += i) {
isPrime[k] = false;
}
}
}
void Print(int num, int leftSosu, int rightSosu) {
cout << num << " = " << leftSosu << " + " << rightSosu << '\n';
}
void Game_Start(int num) {
for (int i = 3; i <= MAX; i+=2) {
if (isPrime[i] == false)continue;
int diff = num - i;
if (diff <= 2) {
cout << "Goldbach's conjecture is wrong.";
break;
}
if (isPrime[diff]) {
Print(num, i, diff);
break;
}
}
}
int main(void) {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
Input_Init();
while (1) {
int num;
cin >> num;
if (num == 0)break;
Game_Start(num);
}
}