Algorithm/baekjoon
[BOJ 9020]골드바흐의 추측
식빵민
2022. 7. 31. 18:15
9020번: 골드바흐의 추측
1보다 큰 자연수 중에서 1과 자기 자신을 제외한 약수가 없는 자연수를 소수라고 한다. 예를 들어, 5는 1과 5를 제외한 약수가 없기 때문에 소수이다. 하지만, 6은 6 = 2 × 3 이기 때문에 소수가 아
www.acmicpc.net
문제 분석
- 시간제한 2초 : 2억 연산 (Big-O 기준)
- 어떤 짝수X가 입력되면 X보다 작은 소수를 구해 두 소수의 합이 X가 되는 경우를 구한다.
- 그 경우가 여러 경우일때, 두 소수의 차가 가장 작은 경우를 구한다.
풀이 방식
- 처음엔 규칙을 구해 그 규칙을 코드로 바꿔보려 했지만, 규칙을 찾지 못했다.
(검색해보니 저명한 수학자들도 그 규칙은 찾지 못했다...) - 짝수 X 보다 작은 모든 소수를 구한다. ( 에라토스테네스의 체 : https://genius00hwan.tistory.com/74 )
- i를 X/2 부터(차가 가장작은 경우) 1씩 감소 시켜 가며 i와 X-i가 소수인지 확인하는 걸 반복한다.
- 소수인 i 와 X-i 를 발견하면 출력하고 반복문을 종료시킨다.
[BOJ 4948]베르트랑 공준
4948번: 베르트랑 공준 베르트랑 공준은 임의의 자연수 n에 대하여, n보다 크고, 2n보다 작거나 같은 소수는 적어도 하나 존재한다는 내용을 담고 있다. 이 명제는 조제프 베르트랑이 1845년에 추측
genius00hwan.tistory.com
#include <iostream>
#include <cmath>
#define MAX 10001
using namespace std;
int n,last, t;
bool isNPrime[MAX]; //false로 초기화
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cin>>t;
while(t--){
cin>>n;
last = n;
for(int i=2;i<=sqrt(last);i++){ //에라토스테네스의 체
for(int j=i;i*j<=last;j++){
isNPrime[i*j] = true; // 소수가 아니면 true
}
}
for (int i = n/2; i >= 2; i--) { // 차가 가장 작은 경우 부터 반복
if (!isNPrime[i]&&!isNPrime[last-i]) { // 소수인 i와 X-i 를 발견하면
cout<<i<<" "<<last-i<<"\n"; // 출력
break; //반복문 종료
}
}
}
}
느낀 점
- 처음에는 모든 경우의 수를 구해 차가 가장 작은 경우를 구하려 했지만 이는 비효율적이고, 시간초과가 날 것 같다는 생각이 들었다.
- 어떻게 하면 효율적일지 생각해 보니 차가 가장 작은 경우 부터 반복하면 되겠다는 생각이 들었다.
- 효율을 따져 가며 문제를 푸니 코드도 깔끔해지고 더 수행시간도 더 효율적이라는 생각이 들었다.
시간 복잡도 (각 테스트 케이스 마다)
- 에라토스테네스의 체 : O(√n * √n) = O(n)
- 소수의 합 구하기 : O(n)
➣ O(n)