λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°

🐍 Python/solve-algorithm

λ°±μ€€ 3460 [μ΄μ§„μˆ˜] : 4가지 풀이 방법과 μ΄μ§„μˆ˜ κ΅¬ν•˜λŠ” ν•¨μˆ˜ κ΅¬ν˜„ν•˜κΈ°

πŸ“Ž Problem

https://www.acmicpc.net/problem/3460

 

3460번: μ΄μ§„μˆ˜

μ–‘μ˜ μ •μˆ˜ n이 μ£Όμ–΄μ‘Œμ„ λ•Œ, 이λ₯Ό μ΄μ§„μˆ˜λ‘œ λ‚˜νƒ€λƒˆμ„ λ•Œ 1의 μœ„μΉ˜λ₯Ό λͺ¨λ‘ μ°ΎλŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€. μ΅œν•˜μœ„ λΉ„νŠΈ(least significant bit, lsb)의 μœ„μΉ˜λŠ” 0이닀.

www.acmicpc.net


πŸ“Ž Solution

μ•Œκ³ λ¦¬μ¦˜ 문제 ν’€μ΄μ—μ„œ 개인적으둜 κ°€μž₯ μ€‘μš”ν•˜κ²Œ μƒκ°ν•˜λŠ” 것은 λ‹€μ–‘ν•œ λ°©λ²•μœΌλ‘œ μ ‘κ·Όν•˜λŠ” 것이닀. ν•œ 문제λ₯Ό 풀더라도, 1가지 λ°©μ•ˆμœΌλ‘œ ν’€μ΄ν–ˆλ‹€κ³  λλ‚˜λŠ” 것이 μ•„λ‹ˆλΌ μ—¬λŸ¬ 번의 μ‹œλ„μ™€ 고민을 톡해 μ„±μž₯ν•  수 μžˆλ‹€. πŸ’ͺ

 

1️⃣ case 1

κ°€μž₯ λ¨Όμ € ν’€μ΄ν•œ λ°©λ²•μœΌλ‘œ 파이썬의 λ‚΄μž₯ν•¨μˆ˜ bin을 ν™œμš©ν•˜μ˜€λ‹€. bin ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λ©΄ μ•žμ— '0b'λΌλŠ” λ¬Έμžκ°€ ν¬ν•¨λœ string ν˜•μ‹μœΌλ‘œ λ¦¬ν„΄λ˜κΈ°λ•Œλ¬Έμ— index slicing으둜 숫자만 μ§€λΌμ£Όμ—ˆλ‹€. βœ‚οΈ python documentation을 μ°Έκ³ ν•˜μ—¬ λ‹€μ–‘ν•œ λ°©λ²•μœΌλ‘œ ν’€μ΄ν•΄λ³΄μž!

 

bin python documentation

 

 

# case 1 : λ©”λͺ¨λ¦¬ 30840KB / μ‹œκ°„ 64ms
T = int(input())

# λ‚΄μž₯ν•¨μˆ˜μΈ bin()을 ν™œμš©ν•˜μ—¬ μ΄μ§„μˆ˜λ‘œ λ°”κΎΈλŠ” 방법 ν™œμš©
for _ in range(T):
    # μˆœμ„œ 거꾸둜
    bnum = list(reversed(bin(int(input()))[2:]))  # 0b 제거 / string type
    # print(bnum)
    for i in range(len(bnum)):
        if bnum[i] == '1':
            print(i, end = ' ')

 


2️⃣ case 2

case1κ³Ό λΉ„μŠ·ν•œ λ°©λ²•μ΄μ§€λ§Œ, μ΄μ§„μˆ˜μ˜ μˆœμ„œλ₯Ό 거꾸둜 λ³€κ²½ν•˜μ§€μ•Šκ³ , index 번호λ₯Ό 거꾸둜 μ£Όμ–΄ ν’€μ΄ν•œ 방법이닀. μ‹œκ°„μ€ case1이 μ•„μ£Ό 쑰금 더 λΉ λ₯΄λ‹€. 인덱슀 번호λ₯Ό -λ₯Ό λΆ™μ—¬ 거꾸둜 ν‘œν˜„ν•˜λŠ” 방법은 자주 μ“°μ΄λ‹ˆ κΈ°μ–΅ν•˜μž! πŸ’‘

 

인덱슀 번호

 

# case 2 : λ©”λͺ¨λ¦¬ 30840KB / μ‹œκ°„ 68ms
T = int(input())

# λ‚΄μž₯ν•¨μˆ˜μΈ bin()을 ν™œμš©ν•˜μ—¬ μ΄μ§„μˆ˜λ‘œ λ°”κΎΈλŠ” 방법 ν™œμš©
for _ in range(T):
    bnum = bin(int(input()))[2:]  # 0b 제거 / string type
    for i in range(len(bnum)):
        # μˆœμ„œ 거꾸둜
        if bnum[-i -1] == '1':
            print(i, end = ' ')

 


3️⃣ case 3

documentation에 μ–ΈκΈ‰λœ κ²ƒμ²˜λŸΌ bin ν•¨μˆ˜λŠ” '0b'κ°€ λΆ™μ–΄μ„œ 좜λ ₯ν•˜κΈ°λ•Œλ¬Έμ— formatμ΄λ‚˜ f-string을 ν™œμš©ν•˜μ—¬ λ‹€λ₯Έ λ°©λ²•μœΌλ‘œ 풀이할 수 μžˆλ‹€.

 

# case 3 : λ©”λͺ¨λ¦¬ 29284KB / μ‹œκ°„ 52ms
T = int(input())
for _ in range(T):
    # f-string ν™œμš©ν•˜μ—¬ 2μ§„μˆ˜λ‘œ λ°”κΏ”μ£Όκ³  μˆœμ„œ 거꾸둜
    bnum = f'{int(input()):2b}'[::-1]
    # bnum = format(int(input()), 'b')  # 같은 ν‘œν˜„
    # print(bnum)
    G = (b for b in range(len(bnum)) if bnum[b] == '1')  # list comprehension
    print(*G)  #unpacking

 


4️⃣ case 4

λ§ˆμ§€λ§‰μœΌλ‘œ μ΄μ§„μˆ˜λ‘œ λ°”κΎΈλŠ” 과정을 μ½”λ“œλ‘œ κ΅¬ν˜„ν•˜μ—¬ λ‚˜λ¨Έμ§€λ₯Ό λ°”λ‘œ ν™•μΈν•˜κ³  좜λ ₯ν•˜λŠ” 방법이 μžˆλ‹€. μ•„λž˜ reference에 μžˆλŠ” λΈ”λ‘œκ·Έλ₯Ό μ°Έκ³ ν•˜μ˜€λ‹€.

# case 4 : λ©”λͺ¨λ¦¬ 30840KB / μ‹œκ°„ 72ms
# μ΄μ§„μˆ˜λ‘œ λ°”κΎΈλ©΄μ„œ λ‚˜λ¨Έμ§€λ‘œ λ°”λ‘œ ν™•μΈν•˜κ³  좜λ ₯
T = int(input())
for _ in range(T):
    n = int(input())
    i = 0
    while n > 0:
        if n % 2 == 1:  # λ‚˜λ¨Έμ§€κ°€ 1이면 좜λ ₯
            print(i, end=' ')
        n = n // 2  # λͺ«
        i += 1

 


πŸ”Ž cf. μ΄μ§„μˆ˜λ‘œ λ§Œλ“œλŠ” ν•¨μˆ˜ 직접 κ΅¬ν˜„

μ΄μ§„μˆ˜λŠ” 2둜 더이상 λ‚˜λˆ„μ–΄μ§€μ§€ μ•Šμ„ λ•ŒκΉŒμ§€ λ‚˜λˆ„κ³ , λ‚˜λ¨Έμ§€λ“€μ„ λͺ¨μ•„μ„œ ꡬ할 수 μžˆλ‹€. ν•΄λ‹Ή 방법을 μ½”λ“œλ‘œ κ΅¬ν˜„ν•˜μ˜€λ‹€.

λ˜ν•œ λ¬Έμ œκ°€ index 번호λ₯Ό 좜λ ₯ν•˜λŠ” κ²ƒμ΄κΈ°λ•Œλ¬Έμ— enumerate ν•¨μˆ˜λ₯Ό ν™œμš©ν•  수 도 μžˆλ‹€.

 

# cf) μ΄μ§„μˆ˜λ‘œ λ§Œλ“œλŠ” ν•¨μˆ˜ 직접 κ΅¬ν˜„
def getBinaryNum(num, result = []):
    a = num // 2
    b = num % 2
    result.append(b)
    if a == 0: return result[::-1]
    else: return getBinaryNum(a, result)

T = int(input())
for _ in range(T):
    bnum = getBinaryNum(int(input()))[::-1]  # 거꾸둜
    # print(bnum)
    # enumerate ν™œμš©ν•˜μ—¬ index 번호 ν”„λ¦°νŠΈν•˜κΈ° & Unpacking
    print(*(i for i, x in enumerate(bnum) if int(x)))  # if int(x) = if 1 = if True

πŸ“Ž Reference