推了一个多小时的式子,ac后一看题解,7行代码搞定

emmmm我还是太菜了

传送

蒟蒻解法:

不管怎么倒水,最终所有瓶子里面的水的数量一定可以用2k表示出来。

n最终可以合并成几个瓶子呢?

我们可以把n分解为多个2k相加的形式,例如:13=23+22+20,所以13最少合并到3个瓶子里面

求n最少能合并到几个瓶子里面,正是看n的二进制表示里面有多少个1

如果1的数量cnt小于等于k,则直接输出0。

否则:从第一个是1的位置+1开始,扫到cnt-k+1个1的位置,中间如果是0,ans就加上2是0的位置,最后ans+2第一个是1的位置

粗略的解释一下

假设某个数的二进制表示是1000101001000,k=2

加上23:1000101010000

加上24:1000101100000

加上25:1000110000000

加上27:1001000000000

对比刚开始的n:100101001000

标0的是加完后最后一个1所在的位置。

我们发现在原始的n的第一个1开始,一直到cnt-k+1的1的位置,中间是0的地方都要在答案上加2k(当然第一个是1的地方除外)

maybe代码会好懂一些

#include<bits/stdc++.h>
using namespace std;
int n,a[],b[],cnt,k,now,ans;//a[i]记录n的二进制表示中,2^i所对应的位上是0还是1,b[i]记录第i个1的位置
long long mi[];//mi[i]为2^i
int read()
{
char ch=getchar();
int x=; bool f=;
while(ch<''||ch>'')
{
if(ch=='-')
f=;
ch=getchar();
}
while(ch>=''&&ch<='')
{
x=(x<<)+(x<<)+(ch^);
ch=getchar();
}
return f?-x:x;
}
void init()
{
mi[]=;
for(int i=;;i++)
{
mi[i]=mi[i-]*;
if(mi[i]>n)break;//mi不开long long见祖宗
}
}
int main()
{
n=read();k=read();
init();
while(n)
{
a[now]=n&;//now代表当前是2^now所代表的位置
if(n&)
{
b[++cnt]=now;
}
now++;
n>>=;
}
if(cnt<=k)//特判
{
printf("");return ;
}
int m=cnt-k+;
ans+=mi[b[]];
for(int i=b[]+;i<=b[m];i++)
{
if(a[i]==)ans+=mi[i];
}
printf("%d\n",ans);
}

大佬做法:

因为所有的水都是由两份相同的水合并而成的,因此每瓶水的体积一定是2^i,(i\in N)2i,(i∈N)升。

最后保留k个瓶子,那么最后总的升数的二进制表示中,1的个数一定<=k。

那么我们只要贪心地往n上加上lowbit(n)即可。

这个lowbit就是树状数组那个lowbit啦

简化代码的trick:

使用内置函数\_\_builtin\_popcount()来计算一个数的二进制表示中1的数量。

这样下来,代码简化到仅剩7行。

惊不惊喜,意不意外?

------------------------摘自洛谷第一篇题解

#include <cstdio>
int n, k, ans;
int main() {
scanf("%d%d", &n, &k);
while(__builtin_popcount(n) > k) ans += n & -n, n += n & -n;
printf("%d", ans);
}

P1582倒水的更多相关文章

  1. 洛谷 P1582 倒水 解题报告

    P1582 倒水 题目描述 一天,CC买了N个容量可以认为是无限大的瓶子,开始时每个瓶子里有1升水.接着~~CC发现瓶子实在太多了,于是他决定保留不超过K个瓶子.每次他选择两个当前含水量相同的瓶子,把 ...

  2. P1582 倒水 (数学)

    P1582 倒水 题目描述 一天,CC买了N个容量可以认为是无限大的瓶子,开始时每个瓶子里有1升水.接着~~CC发现瓶子实在太多了,于是他决定保留不超过K个瓶子.每次他选择两个当前含水量相同的瓶子,把 ...

  3. 洛谷P1582 倒水

    P1582 倒水 题目描述 一天,CC买了N个容量可以认为是无限大的瓶子,开始时每个瓶子里有1升水.接着~~CC发现瓶子实在太多了,于是他决定保留不超过K个瓶子.每次他选择两个当前含水量相同的瓶子,把 ...

  4. 洛谷P1582 倒水 二进制 lowbit __builtin_popcount

    P1582 倒水:https://www.luogu.org/problemnew/show/P1582 题意: 给定n瓶装有1升的水瓶,每次可以把两瓶装水量相同的水和成一瓶,问最少还要增加几瓶装有1 ...

  5. 洛谷 - P1582 - 倒水 - 位运算

    https://www.luogu.org/problemnew/show/P1582 要求用最少的瓶子,那肯定不能有两个一样的瓶子,否则合并更优. 枚举其二进制位,每次加上lowbit,将最后一个1 ...

  6. 洛谷P1582 倒水 二进制的相关应用

    https://www.luogu.org/problem/P1582 #include<bits/stdc++.h> using namespace std; long long N,K ...

  7. P1582 倒水(贪心 + lowbbit)

    https://www.luogu.com.cn/problem/P1582 #include <bits/stdc++.h> using namespace std; #define i ...

  8. P1582 倒水

    传送门 思路: 类似于 袁绍的刁难 , 一道二进制的模拟题. 先将:将原先的瓶子数 n 转换成二进制,二进制中 1 的个数就是合并后剩下的瓶子个数 . 主要利用树状数组的 lowbit 函数: inl ...

  9. 洛谷P1582 倒水题解

    题目 分析 这个题并不难,只是需要仔细思考我们首先可以很轻松的把这个题给疏通一下题意. 1:首先我们最后每个瓶子中装的水一定是一个$2^x$,因为每次都是$2$倍的加,这个应该很好理解. 2:我们要明 ...

随机推荐

  1. Prometheus + AlertManager 邮件报警

    安装 wget https://github.com/prometheus/alertmanager/releases/download/v0.13.0/alertmanager-0.13.0.lin ...

  2. heaplog

    #ifdef _DEBUG #include <stdio.h> #include <stdlib.h> #include <string.h> #define _ ...

  3. (4.31)quotename函数

    操作sql server尤其是写存储过程时,要用到各种各样的函数,今天就总结一个quotename()的用法. 1.语法: quotename(‘character_string’[,‘quote_c ...

  4. mysql-schema-sync同步两个实例

    参考:https://github.com/hidu/mysql-schema-sync 需求:测试环境表结构变动同步到开发环境,两个实例各有数百个库,不适合每个库写一个配置文件 环境:操作系统ubu ...

  5. 简历内容-resume

    1.TCP.UDP通信  服务器客户端  网络层 2.http协议 通信  网络编程  应用层  根据公司给出的应用层协议开发指定程序: 3.json  cjson Cjson解析器 4.freeRT ...

  6. poj-2289.jamies contact groups(二分答案 + 二分多重匹配)

    Jamie's Contact Groups Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 9227   Accepted: ...

  7. React父子组件间的传值

    父组件: import React, { Component } from 'react'; import Child from './chlid'; class parent extends Com ...

  8. Python的魔法方法??

    就是可以给你的类增加魔力的特殊方法,如果你的对象实现 (重载)了这些方法中的某一个,那么这个方法就会在特殊的情况下被 Python 所调用,你可以定义自己想要的行为,而这一切都是自动发生的. __in ...

  9. MVC的view页面内嵌C#语法发现路径被转码的解决方法

    一,上视图代码,如下 console.log('@urlquery.ToString()'); console.log('@Html.Raw(urlquery.ToString())'); 二,显示结 ...

  10. C++基础之static(静态)变量

    static 表示静态   作用: 1.在函数体内,静态变量的值维持不变(记忆功能) 2.是一个本地的全局函数,即只能被本模块的函数访问(隐藏功能)   static变量: static全局变量和普通 ...