algorithm

λ°±μ€€ 1644. μ†Œμˆ˜μ˜ 연속합(투 포인터, μ†Œμˆ˜ κ΅¬ν•˜κΈ°)

μˆ˜ν˜€μ΄0812 2023. 10. 25. 01:14
728x90
λ°˜μ‘ν˜•

문제 😡‍πŸ’«

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

  • 3: 3(ν•œ 가지)
  • 41 : 2+3+4+7+11+13 = 11+13+17 = 41(μ„Έ 가지)
  • 53 : 5+7+11+13+17 = 53(두 가지)

ν•˜μ§€λ§Œ μ—°μ†λœ μ†Œμˆ˜μ˜ ν•©μœΌλ‘œ λ‚˜νƒ€λ‚Ό 수 μ—†λŠ” μžμ—°μˆ˜λ“€λ„ μžˆλŠ”λ°, 20이 κ·Έ μ˜ˆμ΄λ‹€. 7+13을 κ³„μ‚°ν•˜λ©΄ 20이 λ˜κΈ°λŠ” ν•˜λ‚˜ 7κ³Ό 13이 연속이 μ•„λ‹ˆκΈ°μ— μ ν•©ν•œ ν‘œν˜„μ΄ μ•„λ‹ˆλ‹€. λ˜ν•œ ν•œ μ†Œμˆ˜λŠ” λ°˜λ“œμ‹œ ν•œ 번만 λ§μ…ˆμ— μ‚¬μš©λ  수 있기 λ•Œλ¬Έμ—, 3+5+5+7κ³Ό 같은 ν‘œν˜„λ„ μ ν•©ν•˜μ§€ μ•Šλ‹€. 

μžμ—°μˆ˜κ°€ μ£Όμ–΄μ‘Œμ„ λ•Œ, 이 μžμ—°μˆ˜λ₯Ό μ—°μ†λœ μ†Œμˆ˜μ˜ ν•©μœΌλ‘œ λ‚˜νƒ€λ‚Ό 수 μžˆλŠ” 경우의 수λ₯Ό κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.

 

λ‚΄ ν’€πŸ¦·

# 1644. μ†Œμˆ˜μ˜ 연속합

import sys
input = sys.stdin.readline

N = int(input())
prime = []
arr = [True for _ in range(N+1)] 
arr[0] = arr[1] = False
for i in range(2, N+1):
    if arr[i]:
        prime.append(i)
        # i의 2λ°° 이상 λΆ€ν„°λŠ” λ‹€ false...
        for j in range(2*i, N+1, i):
            arr[j] = False

result = start = end = 0
while end <= len(prime):
    each = sum(prime[start:end])
    if each == N:
        result += 1
        end += 1
    elif each < N:
        end += 1
    else:
        start += 1
print(result)

κ³¨λ“œ 3 μš”λŸ‰ν•˜κ³ λŠ” μ—„μ²­ μ–΄λ €μš΄ λ¬Έμ œλŠ” μ•„λ‹ˆμ§€λ§Œ 비ꡐ적 λΉ λ₯Έ μ‹œκ°„μ— μ†Œμˆ˜λ₯Ό κ΅¬ν•˜κ³  또 νˆ¬ν¬μΈν„°λ₯Ό 써야 ν•˜κΈ° 땨문에 두가지 μ•Œκ³ λ¦¬μ¦˜ κ°œλ…μ„ μ•Œκ³  μžˆμ–΄μ•Ό ν•œλ‹€... κ·Έλž˜μ„œ 이거전에 ν’€ 문제둜 μ†Œμˆ˜ κ΅¬ν•˜λŠ” 문제 μΆ”μ²œν•œλ‹€!!!!

 

μ°Έκ³ ν•˜λ©΄ 쒋을 κ°œλ…λ“€ ✍️

  • μ—λΌν† μŠ€ ν…Œλ„€μŠ€μ˜ 체(μ†Œμˆ˜ νŒλ³„ μ•Œκ³ λ¦¬μ¦˜ : μ†Œμˆ˜λ“€μ„ λŒ€λŸ‰μœΌλ‘œ λΉ λ₯΄κ³  μ •ν™•ν•˜κ²Œ κ΅¬ν˜„ν•  수 μžˆλ‹€)
// μ—λΌν† μŠ€ν…Œλ„€μŠ€μ˜ 체λ₯Ό μ‚¬μš©ν•˜μ—¬ μ†Œμˆ˜ κ΅¬ν•˜κΈ°

// 주어진 λ²”μœ„ 내에 μžˆλŠ” 각 μˆ«μžμ— λŒ€ν•΄ μ΄ˆκΈ°μ—λŠ” λͺ¨λ‘ True인 리슀트λ₯Ό μƒμ„±ν•œλ‹€
arr = [True for _ in range(N+1)] 
// 0κ³Ό 1은 μ†Œμˆ˜κ°€ μ•„λ‹ˆλ―€λ‘œ False둜 값을 μ„€μ •ν•œλ‹€
arr[0] = arr[1] = False
// 2λΆ€ν„° NκΉŒμ§€μ˜ 각 μˆ«μžμ— λŒ€ν•΄ μ†Œμˆ˜μΈμ§€ νŒλ³„ν•œλ‹€
for i in range(2, N+1):
	// ν˜„μž¬ μˆ«μžκ°€ μ†Œμˆ˜μΈ 경우, ν•΄λ‹Ή 숫자λ₯Ό μ†Œμˆ˜ λͺ©λ‘μ— μΆ”κ°€ν•˜κ³ ,,,
    // ν˜„μž¬ 숫자의 λ°°μˆ˜λ“€μ„ λͺ¨λ‘ False둜 μ„€μ •ν•œλ‹€... (적어도 iλ₯Ό ν¬ν•¨ν•˜λ‹ˆκΉŒ μ†Œμˆ˜κ°€ μ•„λ‹ˆλ‹€)
    if arr[i]:
        prime.append(i)
        # i의 2λ°° 이상 λΆ€ν„°λŠ” λ‹€ false...
        for j in range(2*i, N+1, i):
            arr[j] = False

 

  • 투 포인터 (λ¦¬μŠ€νŠΈμ— 순차적으둜 μ ‘κ·Όν•΄μ•Ό ν•  λ•Œ 두 개의 점의 μœ„μΉ˜λ₯Ό κΈ°λ‘ν•˜λ©΄μ„œ μ²˜λ¦¬ν•˜λŠ” μ•Œκ³ λ¦¬μ¦˜ ex) νŠΉμ •ν•œ 합을 κ°€μ§€λŠ” λΆ€λΆ„ 연속 μˆ˜μ—΄ μ°ΎκΈ° )
// 투 포인터 κ΅¬ν˜„ν•˜κΈ°

// λ‹€ λ”ν–ˆμ„ 경우 N이 λ˜λŠ” 결과와 μ‹œμž‘, 끝 점을 0으둜 μ΄ˆκΈ°ν™”
result = start = end = 0
// 끝 포인터가 μ†Œμˆ˜μ˜ 길이보닀 μž‘μ„œλ‚˜ 같은 λ™μ•ˆ μˆ˜ν–‰
while end <= len(prime):
	// ν˜„μž¬ μ‹œμž‘λΆ€ν„° κΈ‘κ°€μ§€μ˜ μ†Œμˆ˜ 합을 계산
    each = sum(prime[start:end])
    // 합이 Nκ³Ό κ°™λ‹€λ©΄ κ²°κ³Όλ₯Ό 1 증가, 끝 포인터 λ˜ν•œ 1 증가
    if each == N:
        result += 1
        end += 1
    // 합이 N보닀 μž‘λ‹€λ©΄ 끝 포인터 1 증가
    elif each < N:
        end += 1
    // 합이 N보닀 크닀면 μ‹œμž‘ 포인터 1 증가
    else:
        start += 1
728x90
λ°˜μ‘ν˜•