백준 1644번 소수의 연속합
< 백준 1644번 소수의 연속합 - 마포 코딩박 >
사용한 알고리즘: 에라토스테네스의 체, 투포인터
입력된 어떤 수 N을 연속된 소수의 합으로 나타낼 수 있는 경우의 수를 출력하는 문제입니다.
문제풀이는 다음과 같습니다.
(1) (코드 11~18)
에라토스테네스의 체로 4000000 이하의 소수를 구합니다.
(2) (코드 20~36)
'연속된' 소수들의 합으로 입력된 N 을 나타낼 수 있는 경우의 수를 구합니다.
'연속된' 수의 합이므로 투포인터를 이용해 과정(1)에서 구해놓은 소수들을 처음부터 끝까지 O(N) 의 시간복잡도로 탐색합니다.
사용한 알고리즘: 에라토스테네스의 체, 투포인터
입력된 어떤 수 N을 연속된 소수의 합으로 나타낼 수 있는 경우의 수를 출력하는 문제입니다.
문제풀이는 다음과 같습니다.
(1) (코드 11~18)
에라토스테네스의 체로 4000000 이하의 소수를 구합니다.
(2) (코드 20~36)
'연속된' 소수들의 합으로 입력된 N 을 나타낼 수 있는 경우의 수를 구합니다.
'연속된' 수의 합이므로 투포인터를 이용해 과정(1)에서 구해놓은 소수들을 처음부터 끝까지 O(N) 의 시간복잡도로 탐색합니다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <vector> | |
using namespace std; | |
#define ll long long | |
const int MAX = 4000000; | |
int N; | |
vector<int> prime; | |
bool visited[4000000]; | |
int sum, ans, s, e; | |
int main(){ios_base::sync_with_stdio(false); cout.tie(NULL); cin.tie(NULL); | |
// 에라토스테네스의 체로 소수 구하기 | |
for (ll i = 2; i < MAX; ++i){ | |
if(!visited[i]){ | |
prime.push_back(i); | |
for(ll j=2*i; j < MAX; j+=i) | |
visited[j] = true; | |
} | |
} | |
cin >> N; | |
// 투포인터 | |
// sum : prime[s] 이상 prime[e] 미만 의 소수의 합 | |
// 시작시 sum = 0 | |
while(1){ | |
if(sum>=N){ | |
sum -= prime[s]; | |
s++; | |
} | |
// sum<N 인데 e 가 끝까지 온 경우 | |
else if(e == prime.size()) break; | |
else{ | |
sum += prime[e]; | |
e++; | |
} | |
if(sum == N) ans ++; | |
} | |
cout << ans << '\n'; | |
return 0; | |
} |
댓글
댓글 쓰기
긴 글 읽어주셔서 감사합니다.
궁금한게 있으시다면 댓글 달아주세요!