📃 coding test/◽ 백준
(백준/ C++) 1644 - 소수의 연속 합
핑크코냥
2022. 9. 6. 18:00
728x90
1644번: 소수의 연속합
첫째 줄에 자연수 N이 주어진다. (1 ≤ N ≤ 4,000,000)
www.acmicpc.net
문제 키워드
1. 연속된 소수의 합으로 나타낼 수 있는 자연수
2. 자기 자신이 소수 일 때도 카운트
해결 방법
1. 에라토스테네스의 체 알고리즘을 통해 N이하(N포함)의 소수를 찾아 Vector에 넣는다.
2. vector의 size가 0이 아닐 경우 두개의 index(oneIdx, twoIdx)는 vector의 맨 앞 인덱스 0을 가진다.
3 sum이 N보다 작으면 twoIdx를 클 경우 oneIdx를 증가시킨다.
※ sum은 one과 two 사이의 vector의 합
▼TwoIdx ▲ OneIdx
코드
#include<iostream>
#include<vector>
#include<memory.h>
using namespace std;
// --- 에라토스테네스 채 ---
// --- 연속된 소수의 합 ---
constexpr int limitedNumber = 4'000'000;
bool arr[limitedNumber];
vector<int> primeNumber;
int main(void)
{
ios_base::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int N; cin >> N;
memset(arr, true, sizeof(arr));
arr[0] = arr[1] = false;
for (int i = 2; i <= N / 2; ++i) {
for (int j = i + i; j <= N; j+=i) {
arr[j] = false;
}
}
for (int i = 2; i <= N; ++i)
{
if (arr[i])
{
primeNumber.emplace_back(i);
}
}
int onePointIdx, twoPointIdx, counts = 0, sum = 0 ;
if (primeNumber.size() != 0)
{
onePointIdx = twoPointIdx = 0;
sum = primeNumber[onePointIdx];
}
else
{
cout << "0";
return 0;
}
while (onePointIdx <= twoPointIdx && twoPointIdx < primeNumber.size())
{
if (sum == N)
{
counts++;
twoPointIdx++;
if (twoPointIdx >= primeNumber.size())
break;
sum += primeNumber[twoPointIdx];
}
else if (sum < N)
{
twoPointIdx++;
if (twoPointIdx >= primeNumber.size())
break;
sum += primeNumber[twoPointIdx];
}
else if (sum > N)
{
sum -= primeNumber[onePointIdx];
onePointIdx++;
}
}
cout << counts;
return 0;
}
728x90