
이 문제는 2 이상의 짝수는 소수 두 개의 합으로 이루어져있다는 원리를 이용한 문제이다.
문제 이해
'=' 의 개수가 곧 파티션의 개수
예를 들어보면 아래와 같은 방식으로 2보다 큰 짝수가 소수 두 개의 합으로 이루어진 것을 알 수 있다.
또한, 합치면 짝수가 나오는 두 소수의 세트가 몇 개인지가 파티션의 개수이다.
( 1 ) 6 = 3+3
( 1 ) 8 = 3+5
( 2 ) 10 = 3+7 = 5+5
( 1 ) 12 = 2+6
( 2 ) 14 = 3+11 = 5+7
입출력 형식
[ 입력 ]
- 테스트케이스(T) = 파티션의 개수를 구할 짝수를 몇 개 입력 받을 것인가?
- 짝수(N) = 소수 두 개의 합으로 이루어진 숫자
[ 출력 ]
입력받은 짝수의 파티션 개수 = (짝수를 이루는) 소수 합의 개수

문제점
문제를 풀면서 느낀 가장 큰 문제점 2가지가 있다.
[ 2 ~ 입력받은 짝수 ] 의 소수를 어떻게 구하지?
: 이 문제에 대해서는 에라토스테네스의 체를 이용하였다.
이 문제의 하단에 있는 알고리즘에서도 에라토스테네스의 체를 이용하는 것을 권장하고 있으며, 가장 확실하고 빠르게 소수를 구할 수 있는 방법이었다.
짝수는 다양한 소수로 이루어져있는데 그걸 하나하나 어떻게 찾지?
ex) 5 = (2, 3)의 소수로 이루어져 있다.
이 때 2와 3까지는 구해도 2+2를 해보고 2+3을 해보고 3+3을 해보는 방법을 이용할까 하는 생각을 했지만 이렇게 중첩해서 계산하면 시간복잡도 가 너무 높아졌다.
: [ 2 ~ 입력받은 짝수 ] 중 하나의 수를 n이라고 했을 때 2부터 n까지 돌면서 소수인 수 ( i )를 찾고 ( n-i )도 소수인지 확인한다.
코드풀이
[ 에라토스테네스의 체 ] 함수 부분
static void isPrime(int n) {
for (int i = 2; i <= Math.sqrt(n); i++) {
if (prime[i]) {
continue;
}
for (int j = i * i; j <= n; j += i) {
prime[j] = true;
}
}
}
ex) i = 2 ~ 6 일 때, 소수인 2,3,5(false) 의 배수를 true 처리
[ 전체코드 ]
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class App {
static boolean[] prime;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
int tc = Integer.parseInt(br.readLine());
for (int t = 0; t < tc; t++) {
int n = Integer.parseInt(br.readLine());
int count = 0;
prime = new boolean[n + 1];
prime[0] = prime[1] = true;
isPrime(n);
for (int i = 2; i <= n / 2; i++) {
if (!prime[i] && !prime[n - i]) {
count++;
}
}
sb.append(count).append("\n");
}
System.out.println(sb);
}
static void isPrime(int n) {
for (int i = 2; i <= Math.sqrt(n); i++) {
if (prime[i]) {
continue;
}
for (int j = i * i; j <= n; j += i) {
prime[j] = true;
}
}
}
}
[ 변수 정리 ]
[ 코드 해석 ]
Scanner보다 BufferedReader가 더 빠르게 동작하기 때문에 BufferedReader로 입력받는 객체를 생성해준다.
여러 개의 수에 대한 답을 출력해야하기 때문에 StringBuilder라는 객체를 생성하여 답을 넣고 한번에 출력한다.
가장 먼저 몇 개의 수를 입력 받을지를 변수 tc에 입력받는다.
tc번을 for문을 돌면서 변수 n에 짝수를 하나씩 입력받는다.
n의 홀수인 약수 개수를 구해야하기 때문에 짝수 n을 입력받을 때마다 count도 같이 초기화 해준다.
static으로 선언한 prime 배열을 짝수 개수 n개만큼으로 선언한다.
그리고 0과 1은 소수가 아니기 때문에 for문에 포함되지 않고, 배열 선언과 동시에 true처리한다.
for문을 2부터 n의 반 (n/2)까지 돌리면서 n을 조합하는 소수인 두 수를 찾기 위해서 i와 n-i가 모두 array배열에 false값을 가지고 있는지 (에라토스테네스의 체로 소수인지 검사한 배열) 확인한다.
만약 i와 n-i가 모두 소수라면 count에 1을 추가한다.
입력된 짝수에 대한 답을 sb라는 객체에 넣어주고 for문이 모두 돌아간 후 한번에 출력한다.