题目描述
一天,CC买了N个容量可以认为是无限大的瓶子,开始时每个瓶子里有1升水。接着~~CC发现瓶子实在太多了,于是他决定保留不超过K个瓶子。每次他选择两个当前含水量相同的瓶子,把一个瓶子的水全部倒进另一个里,然后把空瓶丢弃。(不能丢弃有水的瓶子)
显然在某些情况下CC无法达到目标,比如N=3,K=1。此时CC会重新买一些新的瓶子(新瓶子容量无限,开始时有1升水),以到达目标。
现在CC想知道,最少需要买多少新瓶子才能达到目标呢?
输入输出格式
输入格式:一行两个正整数, N,K( 1\le N\le 2\times 10^9,K\le 10001≤N≤2×109,K≤1000 )。
输出格式:一个非负整数,表示最少需要买多少新瓶子。
输入输出样例
本道题要注意是2的几次方,先通过输入的n,不断减去能减去的最大的2的n次方,且将这个n的位置标为1.
这样的话就能得到一个01串,如果1的个数就是瓶子的个数,如果小于k的数量,就输出0,如果不是,就从左往右找第一个1,设该位置为x的话
你就加上2的x次个瓶子,然后推一下判断这时瓶子个数是否少于k个
#include<bits/stdc++.h>
using namespace std;
int a[40];
int biao[40];
int main()
{
int n , k;
cin >> n >> k;
long long maxx = 1 ;
int num = 0;
while(maxx < 2000000000)
{
biao[num] = maxx;
maxx *= 2;
num ++;
}
int sum = 0 , he = 0;
for(int i = num - 1 ;i >= 0 ;i --)
{
if(n >= biao[i])
{
n -= biao[i];
a[i] = 1;
sum ++;
//cout << i << " ";
}
}
//cout << endl;
while(sum > k)
{
int i = 0;
for( i ; i < num ; i ++)
{
if(a[i] == 1)
break;
}
a[i] = 0 ;
he += biao[i];
a[i + 1] ++ ;
for(int j = i + 1; j < num ; j ++)
{
if(a[j] == 2)
{
a[j + 1] ++;
a[j] = 0;
sum --;
}
else
break;
}
}
cout << he;
return 0;
}