[BOJ/C++] 백준 1644번: 소수의 연속합

2024. 10. 2. 18:46·🐸 Problem Solving/BOJ

 

🔗 문제 링크 : https://www.acmicpc.net/problem/1644

 


 

문제

하나 이상의 연속된 소수의 합으로 나타낼 수 있는 자연수들이 있다. 몇 가지 자연수의 예를 들어 보면 다음과 같다.

  • 3 : 3 (한 가지)
  • 41 : 2+3+5+7+11+13 = 11+13+17 = 41 (세 가지)
  • 53 : 5+7+11+13+17 = 53 (두 가지)

하지만 연속된 소수의 합으로 나타낼 수 없는 자연수들도 있는데, 20이 그 예이다. 7+13을 계산하면 20이 되기는 하나 7과 13이 연속이 아니기에 적합한 표현이 아니다. 또한 한 소수는 반드시 한 번만 덧셈에 사용될 수 있기 때문에, 3+5+5+7과 같은 표현도 적합하지 않다.

자연수가 주어졌을 때, 이 자연수를 연속된 소수의 합으로 나타낼 수 있는 경우의 수를 구하는 프로그램을 작성하시오.

 

 

 

 

 

입출력 예시

입력

첫째 줄에 자연수 N이 주어진다. (1 ≤ N ≤ 4,000,000)

 

 

출력

첫째 줄에 자연수 N을 연속된 소수의 합으로 나타낼 수 있는 경우의 수를 출력한다.

 

 

 

입출력 예시

 

 

 


 

풀이 

투 포인터와 소수를 구하는 에라토스테네스의 체를 이용하여 해결하였다.

 

🧩 풀이 과정

  1. 자연수 N를 입력받는다.
    • ❗ 예외 : 1을 입력받을 경우, 1을 연속된 소수의 합으로 나타낼 수 있는 경우의 수는 없으므로 0을 출력하고 프로그램을 종료한다. 
  2. 에라토스테네스의 체를 이용해 자연수 N까지 모든 소수를 구하여, 배열 primeNums에 저장한다. 
  3. 투포인터를 이용해 left부터 right까지의 합이 N이 되는 경우, count를 증가시킨다.
#include <iostream>
#include <vector>
using namespace std;

int main() {
    ios_base::sync_with_stdio(0);
    int N;
    cin >> N;
    if (N == 1) { 
        cout << 0;
        return 0;
    }

    /* 에라토스테네스의 체를 이용한 소수 구하기 */
    vector<bool> isPrime(N+1, true);
    vector<int> primeNums;

    isPrime[0] = isPrime[1] = false;    // 0과 1은 소수가 아니므로 false
    for (int p = 2; p * p <= N; p++) {
        /* 만약 p가 소수이면, */
        if (isPrime[p]) {
            /* p의 배수들을 모두 false로 */
            for (int i = p * p; i <= N; i += p) {
                isPrime[i] = false;
            }
        }
    }

    /* 소수만 배열에 저장하기 */
    for (int i = 2; i <= N; i++) {
        if (isPrime[i])
            primeNums.push_back(i);
    }

    /* 투포인터로 답 구하기 */
    int right = 0;
    int count = 0;
    int sum = primeNums[0];
    for (int left = 0; left <= primeNums.size(); left++) {
        while (right < primeNums.size() && sum <= N) {
            if (sum == N) {
                count++;
                break;
            } 
            right++;
            sum += primeNums[right];
        }
        sum -= primeNums[left];
    }
    cout << count;
}

 

 

 


저작자표시 비영리 변경금지 (새창열림)

'🐸 Problem Solving > BOJ' 카테고리의 다른 글

[BOJ/C++] 백준 2470번: 두 용액  (0) 2024.10.02
[BOJ/C++] 백준 1759번: 암호 만들기  (0) 2024.09.27
[BOJ/C++] 백준 15666번: N과 M (12)  (0) 2024.09.25
'🐸 Problem Solving/BOJ' 카테고리의 다른 글
  • [BOJ/C++] 백준 14940번: 쉬운 최단거리
  • [BOJ/C++] 백준 2470번: 두 용액
  • [BOJ/C++] 백준 1759번: 암호 만들기
  • [BOJ/C++] 백준 15666번: N과 M (12)
Mojing_
Mojing_
매일 매일 경험치를 쌓는 모징이의 개발 블로그입니다 :) This is Mojing’s Dev Blog where she gain experience points every day. :)
  • Mojing_
    모징이의 개발 경험치
    Mojing_
  • 전체
    오늘
    어제
    • 분류 전체보기 (142)
      • 👻 Unity (3)
        • 🔧 기능 구현 (0)
        • 💡 유니티 팁 (0)
        • 📘 Unity 노트 (1)
        • 🏗️ 디자인 패턴 (0)
        • 🎨 그래픽 & 렌더링 (0)
      • 💻 Programming (14)
        • C (3)
        • C++ (9)
        • C# (0)
        • Swift (2)
      • 💾 Computer Science (16)
        • Algorithm (9)
        • Software Engineering (7)
      • 🐸 Problem Solving (108)
        • Programmers (41)
        • BOJ (67)
      • 🔋 ETC (0)
      • 💡 Quest Log (0)
  • 인기 글

  • 공지사항

  • 태그

    C++
    오블완
    sort
    CS
    BOJ
    programmers
    탐색
    Problem Solving
    Design Pattern
    프로그래머스
    dynamic programming
    티스토리챌린지
    algorithm
    DFS/BFS
    backtracking
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Mojing_
[BOJ/C++] 백준 1644번: 소수의 연속합
상단으로

티스토리툴바