파게로그

[백준 9020번] 골드바흐의 추측 본문

콤퓨타 왕왕기초/PS

[백준 9020번] 골드바흐의 추측

파게 2020. 10. 30. 13:00

문제 링크: 9020번 골드바흐의 추측

https://www.acmicpc.net/problem/9020

 

먼저 아리스토텔레스의 체를 통해 소수인지의 여부를 담고있는 배열을 만들어준다. 투 포인터를 사용하여, leftright가 모두 처음에는 n/2를 가리키도록 한다. left를 1씩 감소시키며 그 때마다 right를 갱신하면서, 두 포인터가 가리키는 숫자가 모두 소수가 맞는가를 확인한다. 즉 합(n)이 정해져 있는 경우는 한 쪽(left)만 생각한다.

 

Java

import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; import java.util.StringTokenizer; public class Main { ​​​​public static void main(String[] args) throws IOException { ‌​​​​/* 아리스토텔레스의 체 만들기 */ ​​​​​​​​boolean[] pr = new boolean[10001]; // true: 합성수 ​​​​​​​​pr[1] = true; ​​​​​​​​for (int i = 2; i <= 10000; i++) { ​​​​​​​​​​​​int j = i * 2; ​​​​​​​​​​​​while (j <= 10000) { ​​​​​​​​​​​​​​​​pr[j] = true; ​​​​​​​​​​​​​​​​j += i; ​​​​​​​​​​​​} ​​​​​​​​} ‌‌/* 골드바흐 파티션 찾기 */ ​​​​​​​​BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); ​​​​​​​​int test = Integer.parseInt(new StringTokenizer(br.readLine()).nextToken()); ​​​​​​​​StringBuilder answer = new StringBuilder(); ​​​​​​​​for (int t = 0; t < test; t++) { ​​​​​​​​​​​​int n = Integer.parseInt(new StringTokenizer(br.readLine()).nextToken()); ​​​​​​​​​​​​int left = n / 2; ​​​​​​​​​​​​int right = n - left; ​​​​​​​​​​​​while (left >= 2) { ​​​​​​​​​​​​​​​​if (!pr[left] && !pr[right]) // left, right가 모두 소수인지를 확인 ​​​​​​​​​​​​​​​​​​​​break; ​​​​​​​​​​​​​​​​right = n - --left; // left를 감소시키면 right는 자동으로 갱신 ​​​​​​​​​​​​} ​​​​​​​​​​​​answer.append(left).append(' ').append(right).append('\n'); ​​​​​​​​} ​​​​​​​​System.out.print(answer); ​​​​} }

 

Python

arr_size = 10001 arr = [True] * arr_size # true: 소수, false: 합성수 for i in range(2, arr_size): ​​​​# i가 합성수라면 고려할 필요가 없다. ​​​​if not arr[i]: ​​​​​​​​continue ​​​​# i가 소수라면, i*k(k>=2인 자연수)는 모두 합성수이다. ​​​​for j in range(i*2, arr_size, i): ​​​​​​​​arr[j] = False cases = int(input()) for i in range(cases): ​​​​n = int(input()) ​​​​# left를 n//2부터 1씩 줄여나가면서, n - left가 소수인지 체크 ​​​​left = n//2 ​​​​while (not arr[left]): left -= 1 # left가 소수가 아니면 소수로 할당 ​​​​right = 0 ​​​​while True: ​​​​​​​​right = n - left # n - left 체크 ​​​​​​​​if arr[right]: break ​​​​​​​​left -= 1 ​​​​​​​​while (not arr[left]): left -= 1 # left가 소수가 아니면 소수로 할당 ​​​​print(left, right)

 

Comments