[c++] ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€ :: λ‹€μŒ 큰 숫자 (문제 풀이, μ½”λ“œ)

ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€ 문제

λ‹€μŒ 큰 숫자

https://programmers.co.kr/learn/courses/30/lessons/12911

 

μ½”λ”©ν…ŒμŠ€νŠΈ μ—°μŠ΅ - λ‹€μŒ 큰 숫자

μžμ—°μˆ˜ n이 μ£Όμ–΄μ‘Œμ„ λ•Œ, n의 λ‹€μŒ 큰 μˆ«μžλŠ” λ‹€μŒκ³Ό 같이 μ •μ˜ ν•©λ‹ˆλ‹€. 쑰건 1. n의 λ‹€μŒ 큰 μˆ«μžλŠ” n보닀 큰 μžμ—°μˆ˜ μž…λ‹ˆλ‹€. 쑰건 2. n의 λ‹€μŒ 큰 μˆ«μžμ™€ n은 2μ§„μˆ˜λ‘œ λ³€ν™˜ν–ˆμ„ λ•Œ 1의 κ°―μˆ˜κ°€ κ°™μŠ΅λ‹ˆ

programmers.co.kr

 

문제

문제λ₯Ό 계속 μ—†μ• κΈΈλž˜ 볡사해둔닀.

 

문제 μ„€λͺ…

μžμ—°μˆ˜ n이 μ£Όμ–΄μ‘Œμ„ λ•Œ, n의 λ‹€μŒ 큰 μˆ«μžλŠ” λ‹€μŒκ³Ό 같이 μ •μ˜ ν•©λ‹ˆλ‹€.

  • 쑰건 1. n의 λ‹€μŒ 큰 μˆ«μžλŠ” n보닀 큰 μžμ—°μˆ˜ μž…λ‹ˆλ‹€.
  • 쑰건 2. n의 λ‹€μŒ 큰 μˆ«μžμ™€ n은 2μ§„μˆ˜λ‘œ λ³€ν™˜ν–ˆμ„ λ•Œ 1의 κ°―μˆ˜κ°€ κ°™μŠ΅λ‹ˆλ‹€.
  • 쑰건 3. n의 λ‹€μŒ 큰 μˆ«μžλŠ” 쑰건 1, 2λ₯Ό λ§Œμ‘±ν•˜λŠ” 수 쀑 κ°€μž₯ μž‘μ€ 수 μž…λ‹ˆλ‹€.

예λ₯Ό λ“€μ–΄μ„œ 78(1001110)의 λ‹€μŒ 큰 μˆ«μžλŠ” 83(1010011)μž…λ‹ˆλ‹€.

μžμ—°μˆ˜ n이 λ§€κ°œλ³€μˆ˜λ‘œ μ£Όμ–΄μ§ˆ λ•Œ, n의 λ‹€μŒ 큰 숫자λ₯Ό return ν•˜λŠ” solution ν•¨μˆ˜λ₯Ό μ™„μ„±ν•΄μ£Όμ„Έμš”.

 
μ œν•œ 사항
  • n은 1,000,000 μ΄ν•˜μ˜ μžμ—°μˆ˜ μž…λ‹ˆλ‹€.

 
μž…μΆœλ ₯ 예
n result
78 83
15 23
 
μž…μΆœλ ₯ 예 μ„€λͺ…

μž…μΆœλ ₯ 예#1
문제 μ˜ˆμ‹œμ™€ κ°™μŠ΅λ‹ˆλ‹€.
μž…μΆœλ ₯ 예#2
15(1111)의 λ‹€μŒ 큰 μˆ«μžλŠ” 23(10111)μž…λ‹ˆλ‹€.

 

μ½”λ“œ

#include <string>
#include <vector>

using namespace std;

int numOfOne(int x){
    int i = 1;
    int num=0;
    while(i<=x){
        if((x & i)!=0){ // ν•΄λ‹Ή μžλ¦Ώμˆ˜κ°€ 1이면
            num++;
        }
        i*=2;
    }
    return num;
}

int solution(int n) {
    int answer = 0;
    int cmp = numOfOne(n);
    answer = cmp;

    for(int i=n+1; i<=1000000; i++){
        if(numOfOne(i)==cmp){
            answer = i;
            break;
        }
    }

    return answer;
}

 

풀이

 μš°μ„  문제λ₯Ό λ§ˆμ£Όν•˜κ³  μ™„μ „νƒμƒ‰μœΌλ‘œ ν’€μ–΄μ§€λŠ”μ§€λ₯Ό κ³ λ―Όν–ˆλ‹€. λ³€μˆ˜λŠ” n밖에 μ—†κ³  λ²”μœ„κ°€ 10^6μ΄λ‹ˆ, O(n)μ΄λ‚˜ O(nlgn)의 μ‹œκ°„λ³΅μž‘λ„λ₯Ό 가진 μ•Œκ³ λ¦¬μ¦˜μœΌλ‘œλŠ” 완전탐색이 κ°€λŠ₯ν•  것이닀.

 μ™„μ „νƒμƒ‰μœΌλ‘œ 생각해보면 주어진 n보닀 1큰 n+1λΆ€ν„° n의 μ΅œλŒ€ 값인 1,000,000κΉŒμ§€ 반볡문으둜 λ³΄λ©΄μ„œ ν•΄λ‹Ή μˆ˜κ°€ 2μ§„λ²•μœΌλ‘œ λ‚˜νƒ€λƒˆμ„ λ•Œ, nκ³Ό 같은 1의 개수λ₯Ό 가지고 μžˆλ‹€λ©΄ 정닡을 λ‚΄λŠ” μ‹μœΌλ‘œ ꡬ성할 수 μžˆλ‹€.

 ν•΄λ‹Ή μˆ˜κ°€ nκ³Ό 같은 1의 갯수λ₯Ό 가지고 μžˆλŠ”μ§€λŠ” μ–΄λ–»κ²Œ μ•Œ 수 μžˆμ„κΉŒ? λ‚˜λŠ” λ‹¨μˆœν•˜κ²Œ 1의 갯수λ₯Ό λͺ¨λ‘ μ„Έμ–΄λ³΄λŠ” 방법을 νƒν–ˆλ‹€. 이 κ³Όμ •μ—μ„œ λΉ„νŠΈ 연산을 μ‚¬μš©ν•˜μ—¬ & μ—°μ‚°μœΌλ‘œ 1의 수λ₯Ό μ„Έμ—ˆλ‹€.

 

λΉ„νŠΈ μ—°μ‚° μ„€λͺ…

while(i<=x){
    if((x & i)!=0){ // ν•΄λ‹Ή μžλ¦Ώμˆ˜κ°€ 1이면
        num++;
    }
    i*=2;
}

 

 μ΄λ ‡κ²Œ iκ°€ x보닀 크지 μ•Šμ„λ•ŒκΉŒμ§€, iλ₯Ό 2μ”© κ³±ν•΄μ£Όλ©° &μ—°μ‚°ν–ˆλ‹€. 이 κ²°κ³Όκ°€ 0이 μ•„λ‹ˆλ©΄ ν•΄λ‹Ή μžλ¦Ώμˆ˜λŠ” 1μ΄λΌλŠ” 뜻이기 λ•Œλ¬Έμ— num을 1 μ¦κ°€μ‹œμΌœμ€¬λ‹€. 이 연산은 λΉ„νŠΈ μ‰¬ν”„νŠΈ μ—°μ‚°μœΌλ‘œλ„ κ΅¬ν˜„ν•  수 μžˆλ‹€.

 

κ²°κ³Ό

 μƒκ°λ³΄λ‹€ μ—„μ²­ λΉ λ₯΄κ²Œ μ‹œν–‰λœλ‹€;

 

λ‹€λ₯Έ μ‚¬λžŒμ˜ 풀이

 %2 μ—°μ‚°μœΌλ‘œ 2둜 λ‚˜λˆˆ λ‚˜λ¨Έμ§€λ₯Ό μ°Ύκ³ , /2 μ—°μ‚°μœΌλ‘œ μ‰¬ν”„νŠΈλ₯Ό μˆ˜ν–‰ν•˜λŠ” 풀이도 μžˆμ—ˆλ‹€. λ‚΄ 풀이λ₯Ό μ—­μˆœμœΌλ‘œ λ°”κΎΌ 풀이이닀.

λ°˜μ‘ν˜•