ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【题解】倒水

2020-05-21 13:07:00  阅读:254  来源: 互联网

标签:倒水 10 int 题解 样例 瓶子 二进制 lowbit


题目描述

一天,树树买了N个容量可以认为是无限大的瓶子,初始时每个瓶子里有1升水。树树发现瓶子实在太多了,于是他决定保留不超过K个瓶子。每次他选择两个当前含水量相同的瓶子合并,把一个瓶子里的水全部倒进另一个瓶子,然后把空瓶丢弃(不能丢弃有水的瓶子)。
显然在某些情况下树树无法达到目标,比如N=3,K=1。此时树树会重新买一些新的瓶子(新瓶子容量无限,开始时有1升水),以达到目标。
现在树树想知道,最少需要买多少新瓶子才能达到目标呢?

输入输出格式

输入格式:

一行,两个正整数N,K(1≤N≤\(10^9\),K≤1000)。

输出格式:

一个非负整数,表示最少需要买多少新瓶子。

输入输出样例

输入样例一:

3 1

输出样例一:

1

输入样例二:

13 2

输出样例二:

3

输入样例三:

1000000 5

输出样例三:

15808

说明

样例说明:

考虑lowbit运算。所谓lowbit运算,就是把n的二进制的高位1全部清空,只留下最低位的1,比如10的二进制是1010,则lowbit(n)=lowbit(1010)=0010(二进制)。

数据规模:

对于30%的数据,N≤3×\(10^5\);
对于50%的数据,n≤\(10^7\);
对于100%的数据,如题目所述。

因为题目提示了lowbit运算,所以就是要用位运算
而做位运算的基本思路就是
通过特殊到一般,找出规律
我们来推算一下样例
输入:

3 1

推算:

1 1 1
2 1

把能合并的全部合并后,发现剩下2个,然后把(3)10转换为二进制得到(11)2
也就是说,合并之后所剩下的瓶子个数,就是原数n的二进制中1的个数
那么,到底要买多少个瓶子呢?
题目提示我们考虑lowbit运算

(3)10=(11)2
3+lowbit(3)=(11)2+(1)2=(100)2

也就是说,每加上一个lowbit(n),就会把最低位的1往高位移动,然后就能合并,消除
就是当剩下瓶子数大于K时,就往n中加lowbit(n)
AC代码:

#include<iostream>
using namespace std;
int n,k;
int lowbit(int n)
{
	return n&(-n);
}
int cnt(int n)
{
	int res;
	while(n!=0)
	{
		res+=n%2;
		n/=2;
	}
	return res;
}
int main()
{
	cin>>n>>k;
	int ans=0;
	while(cnt(n)>k)
	{
		ans+=lowbit(n);
		n+=lowbit(n);
	}
	cout<<ans;
}

注意

lowbit(n)=n&(-n)
有可能要用long long

标签:倒水,10,int,题解,样例,瓶子,二进制,lowbit
来源: https://www.cnblogs.com/2021-yanghaoran/p/12930029.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有