题目链接:
对于 n 瓶一升的水,把他们合并后,最少需要的瓶子数为 n 的二进制中 1 的个数。假 设 n 的二进制中 1 的个数大于 k,那么我们要找到 1 个大于 n 的数,且二进制中 1 的个数等 于 k 的最小的数 m,那么答案为 m-n。
假设 n 二进制中,最右边的 1 在第 i 位(这里的第几位是从右往左数的,最右边为第 0 位),那么假设你加上一个小于 2^i 的数,结果二进制中 1 的个数只会增加,如果加上一个 2^i,则结果二进制中 1 的个数必定不会增加。所以只需要一直加上一个 2^i(这里的 i 表示 的是当前水的总体积的二进制中最右边的 1 所在的位置)直到结果中 1 的个数等于 k 即可
1 #include2 #include 3 #define ll long long 4 using namespace std; 5 int cs[100010]; 6 int main() 7 { 8 int t; 9 scanf("%d",&t);10 int n,k;11 while(t--)12 {13 int ans=0;14 scanf("%d%d",&n,&k);15 cs[0]=0;16 int b=0,cnt=1;17 while(n)18 {19 20 if(n&1) cs[cnt++]=1< >=1;22 b++;23 }24 int f=cnt;//杯子25 for(int i=0;i k;i++)26 {27 ans+=(cs[i+1]-cs[i]);28 cs[i+1]<<=1;29 f--;30 }31 printf("%d\n",ans);32 }33 }34 35 /**************************************************************36 Problem: 122837 User: yijiull38 Language: C++39 Result: Accepted40 Time:0 ms41 Memory:2088 kb42 ****************************************************************/
很久之前做的了,粘过来~