Problem Solving/[ν•­ν•΄99] TIL

99클럽 μ½”ν…Œ μŠ€ν„°λ”” 1일차 TIL / 이뢄 탐색

geum 2024. 10. 28. 20:36

✏️ 문제

κΉ€ν˜•νƒμ€ μ§€κΈˆ λͺ°λž˜ Spider Solitaire(μŠ€νŒŒμ΄λ” μΉ΄λ“œλ†€μ΄)λ₯Ό ν•˜κ³  μžˆλ‹€. ν˜•νƒμ΄λŠ” 이 κ²Œμž„μ„ 이길 λ•Œλ„ μžˆμ—ˆμ§€λ§Œ, 질 λ•Œλ„ μžˆμ—ˆλ‹€. λˆ„κ΅°κ°€μ˜ μ‹œμ„ μ΄ λŠκ»΄μ§„ ν˜•νƒμ΄λŠ” κ²Œμž„μ„ μ€‘λ‹¨ν•˜κ³  코딩을 ν•˜κΈ° μ‹œμž‘ν–ˆλ‹€. μ˜μ‹¬μ„ ν”Όν–ˆλ‹€κ³  μƒκ°ν•œ ν˜•νƒμ΄λŠ” λ‹€μ‹œ κ²Œμž„μ„ μΌ°λ‹€. κ·Έ λ•Œ ν˜•νƒμ΄λŠ” μž μ‹œ 코딩을 ν•˜λŠ” 사이에 μžμ‹ μ˜ κ²Œμž„ μ‹€λ ₯이 λˆˆμ— λ„κ²Œ ν–₯μƒλœ 것을 μ•Œμ•˜λ‹€.

이제 ν˜•νƒμ΄λŠ” μ•žμœΌλ‘œμ˜ λͺ¨λ“  κ²Œμž„μ—μ„œ 지지 μ•ŠλŠ”λ‹€. ν•˜μ§€λ§Œ, ν˜•νƒμ΄λŠ” κ²Œμž„ 기둝을 μ‚­μ œ ν•  수 μ—†κΈ° λ•Œλ¬Έμ—, μžμ‹ μ˜ λͺ»ν•˜λ˜ μ˜ˆμ „ 기둝이 ν˜„μž¬ μžμ‹ μ˜ μ—„μ²­λ‚œ μ‹€λ ₯을 증λͺ…ν•˜μ§€ λͺ»ν•œλ‹€κ³  μƒκ°ν–ˆλ‹€.

κ²Œμž„ 기둝은 λ‹€μŒκ³Ό 같이 생겼닀.

 

  • κ²Œμž„ 횟수 : X
  • 이긴 κ²Œμž„ : Y (Z%)
  • ZλŠ” ν˜•νƒμ΄μ˜ 승λ₯ μ΄κ³ , μ†Œμˆ˜μ μ€ 버린닀. 예λ₯Ό λ“€μ–΄, X=53, Y=47이라면, Z=88이닀.

 

X와 Yκ°€ μ£Όμ–΄μ‘Œμ„ λ•Œ, ν˜•νƒμ΄κ°€ κ²Œμž„μ„ μ΅œμ†Œ λͺ‡ 번 더 ν•΄μ•Ό Zκ°€ λ³€ν•˜λŠ”μ§€ κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.

 

πŸ€– μž…μΆœλ ₯ μ˜ˆμ‹œ

 

🧐 λ‚œμ΄λ„/μ†Œμš” μ‹œκ°„

βœ… λ‚œμ΄λ„: solved.ac κΈ°μ€€ S3

βœ… μ†Œμš” μ‹œκ°„: 1μ‹œκ°„ 45λΆ„

βœ… ꢌμž₯ μ‹œκ°„: 45λΆ„

 

πŸ’‘ 풀이

1) 문제 μœ ν˜• νŒŒμ•…

자λ ₯으둜 이뢄 탐색 μœ ν˜•μΈ κ±Έ μ•ˆ 건 μ•„λ‹ˆκ³ , λ°±μ€€μ—μ„œ μ œκ³΅ν•˜λŠ” 'μ•Œκ³ λ¦¬μ¦˜ λΆ„λ₯˜'λ₯Ό 톡해 이뢄 탐색 μœ ν˜•μΈ κ±Έ ν™•μΈν•œ ν›„ 풀이에 λ“€μ–΄κ°”λ‹€. λ‚΄μΌλΆ€ν„°λŠ” 5~10λΆ„ 정도 문제 μœ ν˜•μ΄ 뭔지 슀슀둜 κ³ λ―Όν•΄ λ³Έ 후에 문제λ₯Ό ν’€μ–΄μ•Όκ² λ‹€.

 

ν’€λ‹€ λ³΄λ‹ˆκΉŒ [BOJ] 2003번: μˆ˜λ“€μ˜ ν•© 2 λ¬Έμ œμ™€ λΉ„μŠ·ν•œ 것 같기도 ν•œ λŠλ‚Œμ„ λ°›μ•˜λ‹€.

 

2) 아이디어

β‘  이뢄 탐색 μœ ν˜•μ΄κΈ° λ•Œλ¬Έμ— κ°€μž₯ λ¨Όμ € λ“  생각은 start/end/mid λ³€μˆ˜λ₯Ό 써야겠닀고 μƒκ°ν–ˆλ‹€. 이 λ•Œ 'mid' λ³€μˆ˜μ˜ 값은 (start+end)/2이닀.

 

β‘‘ start λ³€μˆ˜μ˜ μ΄ˆκΈ°κ°’μ€ 1둜 작고 end λ³€μˆ˜μ˜ μ΄ˆκΈ°κ°’μ€ X의 μ œν•œ 값보닀 1 큰 κ°’μœΌλ‘œ μž‘μ•˜λ‹€. end λ³€μˆ˜μ˜ μ΄ˆκΈ°κ°’μ„ μ΄λ ‡κ²Œ μž‘μ€ 건 λ‚΄ μŠ΅κ΄€(μ œν•œ λ²”μœ„λ³΄λ‹€ μ—¬μœ λ‘­κ²Œ μ„€μ •ν•˜λŠ” 것)이라 큰 μ΄μœ κ°€ μžˆλŠ” 것은 μ•„λ‹ˆλ‹€.

 

β‘’ ⭐핡심⭐

μƒˆλ‘œ κ΅¬ν•œ Z κ°’κ³Ό 기쑴의 Z 값을 λΉ„κ΅ν•΄μ„œ 승λ₯ μ˜ λ³€ν™”λ₯Ό μΆ”μ ν•˜λŠ” 뢀뢄이 이 λ¬Έμ œμ™€ 이뢄 탐색 μœ ν˜•μ˜ 핡심이라고 μƒκ°ν•œλ‹€.

 

μƒˆλ‘œμš΄ Z 값이 κΈ°μ‘΄ Z 값보닀 클 경우: μ΅œμ†Œ κ²Œμž„ μˆ˜λŠ” mid 값이 되고, κ³„μ†ν•΄μ„œ μž‘μ€ 값을 μ°Ύμ•„κ°€μ•Ό ν•˜κΈ° λ•Œλ¬Έμ— end λ²”μœ„λ₯Ό mid-1둜 κ°±μ‹ ν•΄ 탐색 λ²”μœ„λ₯Ό μ€„μ—¬μ£Όμ—ˆλ‹€.

 

μƒˆλ‘œμš΄ Z 값이 κΈ°μ‘΄ Z 값보닀 μž‘μ„ 경우: λ‚΄κ°€ μ†μœΌλ‘œ 직접 계산해 λ³Έ λͺ‡ 가지 μ˜ˆμ‹œμ—μ„œλŠ” κ²Œμž„ νšŸμˆ˜κ°€ 늘면 Z 값이 μž‘μ•„μ§€λŠ” κ²½μš°λŠ” μ—†μ—ˆμ§€λ§Œ λ‹¨μˆœνžˆ λ‚΄κ°€ λ°œκ²¬ν•˜μ§€ λͺ»ν•œ κ²ƒμΌμˆ˜λ„ 있기 λ•Œλ¬Έμ— startλ₯Ό mid+1둜 κ°±μ‹ ν•΄ 탐색 μ‹œμž‘μ μ„ λ³€κ²½ν•΄μ£Όμ—ˆλ‹€.

 

β‘£ λ§ˆμ§€λ§‰μœΌλ‘œ μ²˜λ¦¬ν•΄μ€„ 뢀뢄은 -1을 좜λ ₯ν•΄μ•Ό ν•˜λŠ” κ²½μš°μ΄λ‹€. μ΅œμ†Œ κ²Œμž„ 횟수λ₯Ό μ €μž₯ν•  λ³€μˆ˜ min_game의 μ΄ˆκΈ°κ°’μ„ 맀우 큰 κ°’μœΌλ‘œ μ„€μ •ν–ˆκΈ° λ•Œλ¬Έμ— 이 값이 λ°”λ€Œμ§€ μ•Šκ³  μ΄ˆκΈ°κ°’κ³Ό λ˜‘κ°™μ€ μƒνƒœμΌ λ•Œ -1을 좜λ ₯ν•˜λ„λ‘ ν–ˆλ‹€.

 

3) κ΅¬ν˜„

import sys

input = sys.stdin.readline

# X: κ²Œμž„ 횟수, Y: 이긴 κ²Œμž„, Z: Y/X
X, Y = map(int, input().split())

Z = (Y*100)//X

start = 1
end = 1000000001

min_game = float("inf")

while start <= end:
    mid = (start+end)//2
    
    new_Z = ((Y+mid)*100)//(X+mid)

    if new_Z > Z:
        min_game = mid
        end = mid-1
        
        answer = min_game
    else:
        start = mid+1
    
if min_game == float("inf"):
    print(-1)
else:
    print(answer)

 

4) 배운 점/κΆκΈˆν•œ 점

❗ 배운 점

  • start, end λ³€μˆ˜λ₯Ό λ‚΄κ°€ μ›ν•˜λŠ” λ°©ν–₯으둜 μ›€μ§μ΄λ©΄μ„œ 이뢄 탐색 μœ ν˜• λ¬Έμ œμ— ν™œμš©ν•˜λŠ” 법