P1582 倒水 题解
来水一发水题。。
题目链接。
正解开始:
首先,我们根据题意,可以得知这是一个有关二进制的题目;
具体什么关系,怎么做,我们来具体分析:
对于每个n,我们尝试将其二进制分解,也就是100101之类的形式
根据瓶子合并的特性,我们可以判定最后每一个瓶子内的水都可以表示成2^i的形式
感性理解:对于每一个数位上为1的地方,自然,他可以经过多次合并(瓶子加水)来合成,因为每个瓶子内的水都可以表示成2^i的形式,也就对应着n二进制分解上的一个1.
说白了就是从开始的那一堆瓶子里面进行合成,最后在不加瓶子的情况下,必定会合成为n的二进制分解的形式,其中1的个数为瓶子剩余的个数。
那么我们求n的二进制分解中有多少个1,如果1的个数比k小了,说明经过一系列令人窒息的操作后我们在不加瓶子的情况下能够最后剩余的瓶子个数。如果比k要大的话,我们考虑加瓶子:
举个例子:18 用二进制表示的话就是:1010
其中剩余两个瓶子,其中内的水量分别是16L,2L。如果我们要求k=1,也就是只剩下1个瓶子的话,那么我们贪心的考虑,自然买的瓶子量越少越好,也就是从二进制位右边开始,检测1,这时检测到了内含有2L水的瓶子,要想合并,自然要另外找新瓶子并合并成和当前瓶子容量一致的新瓶子,也就是我们还需要1个2L水的瓶子,那么自然的,我们需要两瓶新水,把2累加到答案ans上。
10010+10=10100;
10100+100=11000;
11000+1000=100000;
这时候只剩下1瓶内含有32升水的瓶子。符合k=1的要求
那么答案就是10+100+1000=1110(二进制)=14升水=14个新瓶子。
思路讲解完毕,代码如下:
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int read()
{
int ans=;
char ch=getchar(),last=' ';
while(ch<''||ch>'')last=ch,ch=getchar();
while(ch>=''&&ch<='')ans=(ans<<)+(ans<<)+ch-'',ch=getchar();
return last=='-'?-ans:ans;
}
int n,k,ans;
int lowbit(int x)
{
return x&(-x);
}
int find1(int n)
{
int num=;
while(n>)
{
num+=(n&==?:);
n>>=;
}
return num;
}
int main()
{
n=read();k=read();
while(find1(n)>k)
{
ans+=lowbit(n);n+=lowbit(n);
}
printf("%d",ans);
}
完结
P1582 倒水 题解的更多相关文章
- 洛谷P1582 倒水题解
题目 分析 这个题并不难,只是需要仔细思考我们首先可以很轻松的把这个题给疏通一下题意. 1:首先我们最后每个瓶子中装的水一定是一个$2^x$,因为每次都是$2$倍的加,这个应该很好理解. 2:我们要明 ...
- 洛谷 P1582 倒水 解题报告
P1582 倒水 题目描述 一天,CC买了N个容量可以认为是无限大的瓶子,开始时每个瓶子里有1升水.接着~~CC发现瓶子实在太多了,于是他决定保留不超过K个瓶子.每次他选择两个当前含水量相同的瓶子,把 ...
- P1582 倒水 (数学)
P1582 倒水 题目描述 一天,CC买了N个容量可以认为是无限大的瓶子,开始时每个瓶子里有1升水.接着~~CC发现瓶子实在太多了,于是他决定保留不超过K个瓶子.每次他选择两个当前含水量相同的瓶子,把 ...
- 洛谷P1582 倒水
P1582 倒水 题目描述 一天,CC买了N个容量可以认为是无限大的瓶子,开始时每个瓶子里有1升水.接着~~CC发现瓶子实在太多了,于是他决定保留不超过K个瓶子.每次他选择两个当前含水量相同的瓶子,把 ...
- 洛谷P1582 倒水 二进制 lowbit __builtin_popcount
P1582 倒水:https://www.luogu.org/problemnew/show/P1582 题意: 给定n瓶装有1升的水瓶,每次可以把两瓶装水量相同的水和成一瓶,问最少还要增加几瓶装有1 ...
- P1582倒水
推了一个多小时的式子,ac后一看题解,7行代码搞定 emmmm我还是太菜了 传送 蒟蒻解法: 不管怎么倒水,最终所有瓶子里面的水的数量一定可以用2k表示出来. n最终可以合并成几个瓶子呢? 我们可以把 ...
- 洛谷 - P1582 - 倒水 - 位运算
https://www.luogu.org/problemnew/show/P1582 要求用最少的瓶子,那肯定不能有两个一样的瓶子,否则合并更优. 枚举其二进制位,每次加上lowbit,将最后一个1 ...
- 洛谷P1582 倒水 二进制的相关应用
https://www.luogu.org/problem/P1582 #include<bits/stdc++.h> using namespace std; long long N,K ...
- P1582 倒水(贪心 + lowbbit)
https://www.luogu.com.cn/problem/P1582 #include <bits/stdc++.h> using namespace std; #define i ...
随机推荐
- 【VS开发】CString 转为 char *方法大全
[VS开发]CString 转为 char *方法大全 标签(空格分隔): [VS开发] 方法1: CString strTemp; char szTemp[128]; strTemp = _T(&q ...
- COCO数据集使用
一.简介 官方网站:http://cocodataset.org/全称:Microsoft Common Objects in Context (MS COCO)支持任务:Detection.Keyp ...
- leveldb单元测试之宏定义源码剖析
前言 leveldb 是一个库,没有 main() 函数入口, 故非常难理清其中的代码逻辑.但好在库中有非常多的单元测试代码,帮助读者理解其中的各个模块的功能.然而,测试代码个人觉得一开始看时非常费解 ...
- Java核心1(第三章)
3.6字符串 子串substring(a,b)方法 第二个参数是不想复制的第一个位置 可以从一个较大的字符串中提取一个子串 3.6.2拼接 Java允许使用+号链接两个字符串 3.6.3不可 ...
- js中构造函数与普通函数的区别
构造函数不仅只出现在JavaScript中,它同样存在于很多主流的程序语言里,比如c++.Java.PHP等等.与这些主流程序语言一样,构造函数在js中的作业一样,也是用来创建对象时初始化对象,并且总 ...
- [转帖]ubuntu 修改 apt源的方法
https://www.cnblogs.com/dadonggg/p/11129973.html ubuntu 和 centos 是不一样的 ubunut 里面 用deb开头 放置到 /etc/apt ...
- ORACLE查询进程,并杀死
用于存放常用SQL --查询主键在哪一列 --设置页大小 --设置行大小 col COLUMN_NAME for a20 --设置字段显示长度 col TABLE_NAME for a20 col O ...
- python入门pk小游戏
import time import random flag = True while flag: player_win = 0 enemy_win = 0 for i in range(1, 4): ...
- 初学java3 条件判断
三目运算符 条件? 正确结果:错误结果 if判断 单一条件判断 if(条件){ }else{ } 多种条件判断 if(){ }else if(){ } ... else{ } switch判断 swi ...
- [转载]Grid Search
[转载]Grid Search 初学机器学习,之前的模型都是手动调参的,效果一般.同学和我说他用了一个叫grid search的方法.可以实现自动调参,顿时感觉非常高级.吃饭的时候想调参的话最差不过也 ...