Judge
Programmers - 2개 이하로 다른 비트
깡구_
2022. 6. 24. 11:24
title: Programmers - 2개 이하로 다른 비트
date: 2022-06-23
tags:
- Algorithm
https://programmers.co.kr/learn/courses/30/lessons/77885
문제 요약
주어진 양의 정수 x보다 크지만 다른 비트가 2개 이하인 가장 작은 수를 vector에 집어넣은 후 return한다.
문제 풀이
비트 연산 문제이다. long long 범위이지만 10^15보다 작거나 같으며, 이는 최대 50비트만 확인하면 된다.
2개의 비트가 다르다는 것은 0을 1로 바꾸어 큰 수로 만들고, 그보다 작은 1 비트 중 가장 큰 위치의 비트를 0으로 만드면 된다는 의미이다.
다만, 0을 발견하면 바로 옆 비트는 1 혹은 0이 가장 작은 비트이다. 옆 비트가 0이라면 해당 비트에서 이미 발견하고 처리를 하였어야 한다.
고로 0을 발견하면 해당 비트를 더해주고, 아래의 비트만큼 빼주면 된다.
추가적으로, 다른 유저들의 풀이를 보던 중 감탄이 나오는 풀이를 발견하였다.
프로필을 조회할 수 없어서 입력하신 이름만 가져오는 것이 너무나도 죄송하다.
'김래영' 이라는 분이 작성한 프로그램은 아래와 같다.
'김래영' 님의 프로그램
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
vector<long long> solution(vector<long long> numbers) {
vector<long long> answer;
for(ll& n : numbers) {
ll idx = (~n & -~n);
ll ans = n + idx - (idx >> 1);
answer.push_back(ans);
}
return answer;
}
not 연산과 and 연산을 이용하면 처음으로 0이 나오는 가장 작은 비트를 발견할 수 있다.
이를 이용하여 비트를 탐색하는 과정 없이 바로 값을 구하여 집어넣을 수 있다.
이 정도의 사고를 할 수 있어야 비트 연산을 어느 정도 한다고 말할 수 있을 것 같다.
프로그램
#include <vector>
using std :: vector ;
vector < long long > solution ( vector < long long > numbers )
{
vector < long long > answer ;
long long * llpTemp = numbers.data () ;
int iLen = numbers.size () ;
for ( int i = 0 ; i < iLen ; ++i )
{
for ( int j = 0 ; j <= 50 ; ++j ) // Max 50 bit, but it''s not all 1. So check only 50 bits
{
if ( 0 == ( ( llpTemp [ i ] >> j ) % 2 ) ) // Find 0
{
long long llTemp = 1LL << j ;
answer.emplace_back ( llpTemp [ i ] + llTemp - ( llTemp >> 1 ) ) ;
break ;
}
}
}
return answer ;
}