[λ°±μ€€] 1644번: μ†Œμˆ˜μ˜ 연속합

2020. 12. 25. 20:00γ†πŸ‘¨πŸ»‍🏫 ν”„λ‘œκ·Έλž˜λ°/BOJ(λ°±μ€€)





μ˜€λŠ˜λ„ κΎΈμ€€νžˆ μ•Œκ³ λ¦¬μ¦˜μ„ κ³΅λΆ€ν•΄λ΄…μ‹œλ‹€! 

맀일 κΎΈμ€€νžˆ μ‘°κΈˆμ”© ν’€λ‹€ 보면 저도 μ–Έμ  κ°€ μž˜ν•΄μ§€μ§€ μ•Šμ„κΉŒμš”?

λ©°μΉ  μ•ˆ 남은 20λ…„, λ”μš± νž˜λ‚΄λ΄…μ‹œλ‹€!

문제

ν•˜λ‚˜ μ΄μƒμ˜ μ—°μ†λœ μ†Œμˆ˜μ˜ ν•©μœΌλ‘œ λ‚˜νƒ€λ‚Ό 수 μžˆλŠ” μžμ—°μˆ˜λ“€μ΄ μžˆλ‹€. λͺ‡ 가지 μžμ—°μˆ˜μ˜ 예λ₯Ό λ“€μ–΄ 보면 λ‹€μŒκ³Ό κ°™λ‹€.

  • 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이 λ˜λŠ” 경우의 수λ₯Ό κ΅¬ν•˜λŠ” λ¬Έμ œμ˜€μŠ΅λ‹ˆλ‹€. 

μ΄λ•Œ μ£Όμ˜ν•  점으둜 μ—°μ†λœ μ†Œμˆ˜μ˜ 합을 ꡬ할 λ•Œ, 각각의 μ†Œμˆ˜λŠ” 단 ν•œ λ²ˆμ”©λ§Œ 더해져야 ν•œλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€.

그러렀면 λ¨Όμ € N μ΄ν•˜μ˜ μ†Œμˆ˜λ₯Ό λ¨Όμ € ꡬ해야 κ² μ£ ? N의 μ΅œλŒ€ 크기가 400만이기 λ•Œλ¬Έμ— 효율적이라고 널리 μ•Œλ €μ§„ μ—λΌν† λ„€μŠ€μ˜ 체 λ°©λ²•μ„ μ΄μš©ν•˜μ—¬ μ†Œμˆ˜ 배열을 κ΅¬ν•΄λ³΄μ•˜μŠ΅λ‹ˆλ‹€.

Nμ΄ν•˜μ˜ μ†Œμˆ˜λ°°μ—΄μ„ κ΅¬ν•˜κ³  μ—°μ†λœ μ†Œμˆ˜μ˜ 뢀뢄합을 κ΅¬ν•˜κΈ° μœ„ν•΄ νˆ¬ 포인터 기법을 μ‚¬μš©ν•˜μ—¬ 뢀뢄합이 N이 λ˜λŠ” κ΅¬κ°„μ˜ 수λ₯Ό ꡬ할 수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

#include<bits/stdc++.h>

using namespace std; int N,l,r,ans; vector primes,nums; // μ—λΌν† λ„€μŠ€μ˜ 체 void getPrimes(int N){ nums.resize(N+1,1); //nums λ°°μ—΄ 1둜 μ΄ˆκΈ°ν™” for(int i=2;i<=sqrt(N);i++){ if(!nums[i]) continue; //μ–΄λ–€ 수의 배수인 수둜 μ²΄ν¬λ˜μ—ˆμœΌλ―€λ‘œ continue; for(int j=2*i;j<=N;j+=i){ nums[j]=0; } } for(int i=2;i<=N;i++)if(nums[i]) primes.push_back(i); return; } int main(){ ios_base::sync_with_stdio(false); cin.tie(0); cin>>N; getPrimes(N); int vecSize=(int)primes.size(); //μ†Œμˆ˜ λ°°μ—΄μ˜ 크기 int partialSum=0; // λΆ€λΆ„ ν•© λ³€μˆ˜ // 투 포인터 while(1){ if(partialSum>=N) partialSum-=primes[l++]; // λΆ€λΆ„ν•© κ°μ†Œ else if(r==vecSize) break; else partialSum+=primes[r++]; // λΆ€λΆ„ν•© 증가 if(partialSum==N) ans++; } cout<<ans<<"\n"; return 0; }


λΆ€μ‘±ν•œ λΆ€λΆ„μ΄λ‚˜ κΆκΈˆν•œ λΆ€λΆ„ λŒ“κΈ€ κ°μ‚¬ν•˜κ² μŠ΅λ‹ˆλ‹€!.