문제

양의 정수 n이 주어졌을 때, 이를 이진수로 나타냈을 때 1의 위치를 모두 찾는 프로그램을 작성하시오. 최하위 비트(least significant bit, lsb)의 위치는 0이다.

  • 입력
    • 첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스는 한 줄로 이루어져 있고, n이 주어진다. (1 ≤ T ≤ 10, 1 ≤ n ≤ \(10^6\))
  • 출력
    • 각 테스트 케이스에 대해서, 1의 위치를 공백으로 구분해서 줄 하나에 출력한다. 위치가 낮은 것부터 출력한다.

코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <bitset>
#include <string>
#include <algorithm>
#include <vector>
using namespace std;

int main(void){
    int num;

    cin >> num;

    for (int i = 1; i <= num; i++){
        int n;

        cin >> n;
        
        string bits = bitset<30>(n).to_string();
        reverse(bits.begin(), bits.end());

        vector<int> v;

        for (int i = 0; i < 30; i++){
            if(bits[i] == '1') v.push_back(i);
        }

        for (int i = 0; i < v.size(); i++){
            cout << v[i] << " ";
        }

        cout << endl;

        v.clear();
    }

    return 0;
}

접근 및 풀이

<bitset> 헤더를 처음 이용해보면서 기억하기 위해 기록하는 문제이다.
std::bitset - C++ 해당 링크를 확인해보면 bitset STL의 활용법을 더 잘 알 수 있을 것이다. bitset<size>(n)를 실행하면 해당 n을 size 크기의 이진수로 바꾸어 나타내준다. 남는 자릿수는 0으로 채워진다. n의 범위가 \(10^6\)이고 이는 2의 28승을 좀 넘었던 걸로 기억해서 넉넉하게 30의 size로 맞춰주었다.

나타낸 이진수를 문자열로 바꾸어 준 뒤 문자열을 뒤집어주면 가장 최하위 비트가 문자열의 0번째로 오게 되면서 문제에서 주어진 위치와 숫자가 매치되게 된다. 그렇게 문자열의 문자를 보면서 해당 문자가 ‘1’인 경우 해당 위치를 벡터에 기록하도록 한 뒤 위치를 출력해 주었다.

댓글남기기