본문 바로가기
PS

[C++] 백준 9020 - 골드바흐의 추측

by gamxong 2023. 2. 24.

난이도 : 실버 2

 

 

풀이 방법

첫번째로 생각한 방법은 입력크기를 고려하여 10000까지의 소수를 구하고, 그 후 입력값에 동일한 두 값의 덧셈을 구하려고 했다.

소수를 구하는 코드는 구구단처럼 2단부터 시작해서 10000단까지 10000이하인 수는 arr[n] = 1로 처리했다.
예를 들면 2x3=6은 소수가 아니기 때문에 arr[6] = 1 으로 처리.


따라서 arr[n] = 0 인 n은 소수가 된다.

그 후 2부터 입력된 값까지 소수 덧셈의 모든 경우의 수 중에서 두 수의 차가 가장 적은 것을 출력했다.

 

초기 코드 (시간초과)

#include <iostream>
#include <cstring>
#include <algorithm>
#include <climits>

using namespace std;

int T;
int arr[10001];

int main(void){
    scanf("%d", &T);
    
    for(int i=0; i<T; i++){
        int input = 0;
        int diff = INT_MAX;
        int X = 0, Y = 0;
        
        scanf("%d", &input);
        for(int i=2; i<=input; i++){
            for(int j=2*i; j<=input; j+=i){
                arr[j] = 1;
            }
        }
        
        for(int i=2; i<=input; i++){
            if(arr[i] == 0){
                for(int j=i; j<=input; j++){
                    if(arr[j] == 0){
                        if(input<i+j)
                            break;
                        if(input == i + j){
                            int tmp = j - i;
                            if(tmp < diff){
                                diff = tmp;
                                X = i;
                                Y = j;
                            }
                        }
                    }
                }
            }
        }
        printf("%d %d\n", X, Y);
    }
}

일단 굉장히 지저분한 if문이 눈에 띈다.
성공도 하지 못했다. 시간초과가 발생하였다.
어느 부분에서 시간을 줄일지 고민했다.
먼저 소수를 구하는 코드는 저 방법이 최선이라고 생각했다.

결국 입력 값에 대한 두 수의 덧셈을 어떻게 구현하냐가 핵심이다.

문제에서 입력 값은 짝수이며 두 소수의 덧셈이 해당 입력 값이 되는 경우가 무조건 존재한다. 또한, 문제에서 두 수의 차가 가장 적은 경우를 출력해야 했기에 심플하게 해당 짝수를 2로 나눈 두 수부터 소수인지 검사하는 코드를 작성했다. 소수가 아니라면 해당 수를 +1, -1해서 가장 효율적으로 찾을 수 있게 작성했다.

 

최종 코드

#include <iostream>
#include <cstring>
#include <algorithm>
#include <climits>

using namespace std;

int T;
int arr[10001];

int main(void){
    scanf("%d", &T);
    
    for(int i=0; i<T; i++){
        int input = 0;
        int diff = INT_MAX;
        int X = 0, Y = 0;
        
        scanf("%d", &input);
        for(int i=2; i<=input; i++){
            for(int j=2*i; j<=input; j+=i){
                arr[j] = 1;
            }
        }
        
        int tmp1 = input/2;
        int tmp2 = input/2;
        
        
        while (X == 0 && Y == 0) {
            
            if(arr[tmp1] == 0 && arr[tmp2] == 0){
                X = tmp1;
                Y = tmp2;
            }else{
                tmp1++;
                tmp2--;
            }
        }
        
        printf("%d %d\n", Y, X);
    }
}

'PS' 카테고리의 다른 글

[C++] 백준 1541 - 잃어버린 괄호  (0) 2023.02.24
[C++] 백준 2565 - 전깃줄  (0) 2023.02.24
[C++] 백준 18870 - 좌표 압축  (0) 2023.02.24
[C++] 백준 2447 - 별찍기 - 10  (0) 2023.02.24
[C++] 백준 1002 - 터렛  (0) 2023.02.24

댓글