[백준 1052번 C/C++] 물병
[백준 1052번 C/C++] 물병
https://www.acmicpc.net/problem/1052
해결전
수학
그리디 알고리즘
비트마스킹
각 물병은 서로 다른 물병과 합쳐질 수 있다. 이 합치는 과정은 물병의 2진수로 표현한다.
- 예를 들어, 물병 3개(2진수로 11)를 2개씩 합치면 2진수 100이 되어 물병 1개가 된다.
물병을 모두 합쳐서 k개의 물병 이하로 만들어야 한다.
- n이 k보다 작거나 같으면 추가 물병이 필요 없으므로 0을 반환합니다.
- 비트마스킹
- n의 2진수 표현에서 1의 개수는 현재 물병의 수가 어떻게 조합될 수 있는지를 나타낸다.
- int BitCnt(int x)
- n의 2진수 표현에서 1의 개수가 k보다 많으면, 물병을 추가하여 이 개수를 줄여야 한다. 이를 위해 n을 하나씩 증가시키면서 1의 개수가 k 이하가 될 때까지 반복한다.
- while( BitCnt(temp) > k )
- n의 2진수 표현에서 1의 개수는 현재 물병의 수가 어떻게 조합될 수 있는지를 나타낸다.
정답코드
#include <iostream>
using namespace std;
int n, k; // n: 현재 물병 수, k: 하나로 만들 수 있는 물병의 최대 수
int answer; // 필요한 추가 물병 수
// 주어진 정수 x의 2진수 표현에서 1의 개수를 세는 함수
int BitCnt(int x)
{
int cnt = 0; // 1의 개수를 세기 위한 변수
while(x)
{
cnt += (x & 1); // x의 마지막 비트가 1이면 cnt를 증가
x >>= 1; // x를 오른쪽으로 1비트 이동
}
return cnt;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> n >> k;
if (n <= k){ // 현재 물병 수가 k 이하이면 추가 물병이 필요 없으므로
cout << "0"; // 0을 출력
return 0;
}
int temp = n;
while (BitCnt(temp) > k) // temp의 2진수 표현에서 1의 개수가 k보다 많으면
{
temp++;
answer++; // 필요한 추가 물병 수를 1 증가
}
cout << answer;
return 0;
}
코드 비교
주어진 정수 x의 2진수 표현에서 1의 개수를 세는 함수
비트마스킹 형태의 표기
int BitCnt(int x)
{
int cnt = 0; // 1의 개수를 세기 위한 변수
while(x)
{
cnt += (x & 1); // x의 마지막 비트가 1이면 cnt를 증가
x >>= 1; // x를 오른쪽으로 1비트 이동
}
return cnt;
}
다른 버젼
int BitCnt(int x)
{
int cnt = 0; // 1의 개수를 세기 위한 변수
while(x)
{
if (x % 2 != 0){ // x를 2로 나눈 나머지가 1이면 (즉, x의 현재 비트가 1이면)
cnt++; // 1의 개수 증가
}
x /= 2;
}
return cnt;
}
'⭐ 코딩테스트 > 백준' 카테고리의 다른 글
[백준 15661번 C++] 링크와 스타트 (0) | 2024.08.06 |
---|---|
[백준 11723번 C/C++] 집합 (0) | 2024.08.05 |
[백준 16938번 C/C++] 캠프 준비 (0) | 2024.08.02 |
[백준 2961번 C/C++] 도영이가 만든 맛있는 음식 (0) | 2024.08.01 |
[백준 2800번 C/C++] 괄호 제거 (0) | 2024.07.31 |
댓글
이 글 공유하기
다른 글
-
[백준 15661번 C++] 링크와 스타트
[백준 15661번 C++] 링크와 스타트
2024.08.06 -
[백준 11723번 C/C++] 집합
[백준 11723번 C/C++] 집합
2024.08.05 -
[백준 16938번 C/C++] 캠프 준비
[백준 16938번 C/C++] 캠프 준비
2024.08.02 -
[백준 2961번 C/C++] 도영이가 만든 맛있는 음식
[백준 2961번 C/C++] 도영이가 만든 맛있는 음식
2024.08.01