티스토리 뷰
문제
풀이 과정
저번에 소수 문제를 풀어봤으니 이어서 소수 카테고리를 마저 풀기로 했다.
지난 번에 2581번에서 썼던 소수 구하는 알고리즘을 다음과 같이 조금 개선했다.
#include <iostream>
#include <vector>
bool isPrime(int n)
{
if (n == 2)
return true;
if (n == 1 || n % 2 == 0)
return false;
for (int j = 3; j * j <= n; j+= 2)
{
if (n % j == 0)
return false;
}
return true;
}
2가 아닌 짝수일 경우 절대 소수가 아니므로
반복문을 돌리기 전에 n이 2일 때는 true를 return하고, 짝수일 때는 false를 return하도록 바꿔주고 3에서부터 2씩 더해가면서 n을 나눠봄으로써 반복 횟수를 줄여봤다.
이제 2보다 큰 짝수가 주어지면 그 짝수의 소수 인수를 구해야 한다.
그런데 문제에서 n의 골드바흐 파티션이 여러 쌍인 경우 두 소인수의 차가 가장 작은 경우만 출력하라고 했으므로, n을 2로 나눈 지점부터 시작하고 찾으면 끝내는 식으로 코드를 짜는 것이 바람직할 것으로 생각했다.
n은 짝수이기 때문에 무조건 2로 나누어 떨어진다.
이 나눠진 두 조각을 left와 right라고 하자. 최초에는 left와 right가 동일하다.
만약 left가 2가 아닌 짝수인 경우 절대 소수일 수 없으므로
left에서는 1을 빼주고 right에서는 1을 더해준다.
(left가 2인 경우에는 4 = 2x2로, 파티션이 바로 끝난다.)
그럼 두 수는 홀수가 되고, 소수일 가능성이 생긴다.
이제 isPrime 함수를 거쳐 left와 right가 소수인지 확인하고, 둘 다 소수라면 가장 차가 적은 경우의 파티션을 찾았다.
둘 다 소수가 아닌 경우, left에서는 2를 빼고 right에서는 2를 더해가면서 다시 두 수가 소수인지를 검사한다. 두 수 모두 소수일 경우, 파티션을 찾았으니 반복문을 끝내면 된다.
이를 그대로 소스코드로 작성하면 다음과 같다.
파티션 과정을 진행하는 goldbachPartition 함수에서 소인수 2개를 return하기 위해 results라는 배열을 만들어 넣어주었다.
#include <iostream>
#include <vector>
using namespace std;
bool isPrime(int n)
{
if (n == 2)
return true;
if (n == 1 || n % 2 == 0)
return false;
for (int j = 3; j * j <= n; j+= 2)
{
if (n % j == 0)
return false;
}
return true;
}
vector<int> goldbachPartition(int n)
{
int left, right;
vector<int> results; // 결과를 담은 배열
results.resize(2);
left = right = n / 2;
if (left % 2 == 0 && left != 2) // 2로 나눈 것이 2가 아닌 짝수일 경우 절대 소수가 될 수 없으므로
{
left -= 1;
right += 1;
}
if (isPrime(left) && isPrime(right)) // 소수인지 확인해서 둘 다 소수이면 파티션 성공
{
results[0] = left;
results[1] = right;
}
else
{
while (left >= 2)
{
left -= 2;
right += 2;
if (isPrime(left) && isPrime(right)) // 소수인지 확인해서 둘 다 소수이면 파티션 성공, 반복문 끝냄
{
results[0] = left;
results[1] = right;
break;
}
}
}
return results;
}
int main(void)
{
int test = 0;
cin >> test;
for (int t = 0; t < test; t++)
{
int n = 0;
cin >> n;
vector<int> results;
results = goldbachPartition(n);
printf("%d %d\n", results[0], results[1]);
}
return 0;
}
좀 더 생각해보면 더 효율적으로 짤 수도 있을 것 같으나 귀찮으니 패쓰~~~![]()
'알고리즘 > BOJ' 카테고리의 다른 글
| [BOJ] 10828 - 스택 (0) | 2018.05.11 |
|---|---|
| [BOJ] 2581 - 소수, 1929 - 소수 구하기 (0) | 2018.04.30 |
| [BOJ] 1316 - 그룹 단어 체커 (0) | 2018.04.16 |
| [BOJ] 2292 - 벌집 (0) | 2018.04.15 |
| [BOJ] 4344 - 평균은 넘겠지 (0) | 2018.04.03 |
- Total
- Today
- Yesterday
- 가상머신
- C++
- 윈도우xp
- # 보안 # 나만의 # 백신 # 만들기 #안티 #바이러스 #파이썬 #악성코드
- VirtualBox
- Leap motion
- Leap motion stick
- Leap motion pen
- Leap motion pencil
- Leap motion SDK
- Tool Tracking
- windows10
- 립 모션
- WindowsXP
- 툴
- VMware
- 설치
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | ||||||
| 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| 9 | 10 | 11 | 12 | 13 | 14 | 15 |
| 16 | 17 | 18 | 19 | 20 | 21 | 22 |
| 23 | 24 | 25 | 26 | 27 | 28 | 29 |
| 30 |
