倒水
【题目描述】
一天,树树买了 N 个容量可以认为是无限大的瓶子,初始时每个瓶子里有 1 升水。
树树发现瓶子实在太多了,于是他决定 保留不超过 K 个瓶子。每次他选择两个当前含
水量相同的瓶子合并,把一个瓶子的水全部倒进另一个瓶,然后把空瓶丢弃(不能丢
弃有水的瓶子)。
显然在某些情况下树树无法达到目标,比如 N=3,K=1.此时树树会重新买一些新
的瓶子(新瓶子容量无限,开始时有 1 升水),以达到目标。
现在树树想知道,最少需要买多少新瓶子才能达到目标呢?
【输入文件】
一行两个正整数 N,K(1<=N<=10 9 ,K<=1000)。
【输出文件】
一个非负整数,表示最少需要买多少新瓶子。
【样例输入】
3 1
【样例输出】
1
【数据规模】
对于 30%的数据,N<=3*10 5
对于 100%的数据如题目。
把能合并的合并,发现剩下的瓶子是n二进制数中1的个数
如果大于k,那么就要从小位消除
消除方法就是给原数不断加上lowbit(n)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 long long n,k,ans; 8 long long count(long long x) 9 { 10 int cnt=0; 11 while (x) 12 { 13 x-=(x&(-x)); 14 cnt++; 15 } 16 return cnt; 17 } 18 int main() 19 { 20 cin>>n>>k; 21 ans=0; 22 while (count(n)>k) 23 { 24 ans+=(n&(-n)); 25 n+=(n&(-n)); 26 } 27 cout<<ans; 28 }