[백준] 1644 소수의 연속합 (JAVA)

2025. 10. 19. 15:31·코딩 테스트

문제 링크:

1644번: 소수의 연속합

 

 

난이도: 골드 3

 

 

문제:

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

  • 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을 연속된 소수의 합으로 나타낼 수 있는 경우의 수를 출력한다.

 

 

문제 이해:

이 문제는 자연수 N이 주어졌을 때, 그 수를 연속된 소수의 합으로 표현할 수 있는 경우의 수를 구하는 문제이다.

예를 들어, N = 41인 경우를 살펴보면,

  • 41 = 2 + 3 + 5 + 7 + 11 + 13
  • 41 = 11 + 13 + 17
  • 41 = 41

즉, 세 가지 방법으로 41을 연속된 소수의 합으로 나타낼 수 있다.

 

 

구현 방향:

소수와 관련된 문제는 대부분 에라토스테네스의 체를 사용한다.
이 알고리즘은 2부터 시작하여, 특정 수의 배수를 모두 제거(또는 false로 표시)함으로써 소수를 효율적으로 판별할 수 있다.
따라서 2부터 N의 최대값인 4,000,000까지 반복하며, 각 인덱스에 해당하는 수가 소수인지를 판별하고, 그 배수들을 모두 false로 세팅하면 된다.

 

연속된 소수의 합으로 N을 표현할 수 있는 경우의 수를 구하기 위해 처음에는 적절한 알고리즘을 떠올리지 못했으나, 자료를 찾아본 결과 투 포인터(Two Pointers) 알고리즘을 사용하는 것이 적합하다는 것을 알게 되었다.
이 알고리즘은 주로 다음과 같은 상황에서 활용된다.

  • 두 수의 합, 차, 곱, 조건 비교
  • 연속된 부분합
  • 중복 없는 부분 문자열 탐색
  • 슬라이딩 윈도우 문제

투 포인터 알고리즘의 핵심은 두 개의 포인터(left, right)를 이용해 구간의 합을 유지하며, 합이 너무 작으면 오른쪽 포인터를 이동시키고, 합이 너무 크면 왼쪽 포인터를 이동시키는 방식이다.

 

예) N=7, 소수=[2,3,5,7,…] →
① left=0,right=0,sum=2(작음)→right++ →
② left=0,right=1,sum=5(작음)→right++ →
③ left=0,right=2,sum=10(큼)→left++ →
④ left=1,right=2,sum=8(큼)→left++ →
⑤ left=2,right=2,sum=5(작음)→right++ →
⑥ left=2,right=3,sum=12(큼)→left++ →
⑦ left=3,right=3,sum=7(정답)→count++.

 

이를 코드로 그대로 구현하면 다음과 같다.

 

 

정답코드:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;

public class Main {
    static boolean []primes= new boolean[4000001];
    static int N;
    static int result=0;

    //소수만 true 활성화
    public static void primesSet(){
        primes[1]=false;
        for(int i=2; i<4000001; i++){
            if(!primes[i]) continue;

            else{
                for(int j=2*i; j<4000001; j+=i){
                    primes[j]=false;
                }
            }
        }
    }

    //투포인터 알고리즘을 이용하여 해결
    public static void solve(){
        int target=N;
        int left=2;
        int sum=0;
        boolean flag=true;
        for(int R=2; R<=N; R++){
            if(primes[R]){
                sum += R;
                flag=true;
            }

            //왼쪽 한칸 전진
            while (sum > target && left <= R){
                sum -= left;
                for(int i=left+1; i<=N; i++){
                    if(primes[i]){
                        left=i;
                        break;
                    }
                }
            }

            //소수의 합들이 입력한 N이면 개수 증가
            if (flag && sum == target){
                result++;
                flag=false;
            }
        }
    }

    public static void main(String[] args) throws IOException {
        //초기 세팅
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        N=Integer.parseInt(br.readLine());
        Arrays.fill(primes, true);
        //초기 세팅 끝

        //에라토스테네스의 체 적용하여 소수만 ture
        primesSet();

        //탐색 시작
        solve();

        //결과 출력
        System.out.println(result);
    }
}

 

 

마무리하며:

코딩 테스트를 연습하면서 투 포인터 방식의 문제는 처음 풀어본 것 같다.
하지만 이론 자체가 복잡하거나 어려운 개념은 아니기 때문에, 꾸준히 연습하면 금방 익숙해질 것 같다.
특히 처음 투 포인터 알고리즘을 접하는 사람들에게는 이 문제가 좋은 연습문제가 될 것이다.

 

감사합니다.

'코딩 테스트' 카테고리의 다른 글

[백준] 3273 두 수의 합 (JAVA)  (0) 2025.10.21
[백준] 13144 List of Unique Numbers (JAVA)  (0) 2025.10.20
[백준] 1202 보석 도둑 (JAVA)  (0) 2025.10.16
[백준] 1931 회의실 배정 (JAVA)  (0) 2025.10.14
[백준] 14469 소가 길을 건너간 이유 3 (JAVA)  (0) 2025.10.13
'코딩 테스트' 카테고리의 다른 글
  • [백준] 3273 두 수의 합 (JAVA)
  • [백준] 13144 List of Unique Numbers (JAVA)
  • [백준] 1202 보석 도둑 (JAVA)
  • [백준] 1931 회의실 배정 (JAVA)
0kingki_
0kingki_
자바 + 스프링 웹 개발
  • 0kingki_
    0kingki_
    0kingki_
  • 전체
    오늘
    어제
    • 분류 전체보기 (134)
      • 코딩 테스트 (54)
      • 자바 (21)
      • 스프링 (27)
      • 타임리프 (16)
      • 스프링 데이터 JPA (8)
      • 최적화 (2)
      • QueryDSL (4)
      • AWS (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    재귀
    spring
    컬렉션
    Java
    스프링 데이터 JPA
    코딩 테스트
    fetch join
    mvc
    예외처리
    스프링 컨테이너
    백준
    스프링
    최적화
    thymeleaf
    SpringDataJpa
    예외 처리
    SOLID
    쿼리
    dfs
    QueryDSL
    쿼리dsl
    불변객체
    JPA
    자바
    BFS
    객체지향
    다형성
    LocalDateTime
    타임리프
    코딩테스트
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
0kingki_
[백준] 1644 소수의 연속합 (JAVA)
상단으로

티스토리툴바