倒水(rms2017模拟2-1)* 【推理】
来源:互联网 发布:编程cim是做什么的 编辑:程序博客网 时间:2024/05/17 05:50
倒水(water.cpp)
试题描述: 某一天,在 NH 学习 CS 的 ZR 习得新的 ACM 秘籍,惊奇的发现,每使用一次会额外
得到一个容量无限大的瓶子,并且初始时每个瓶子里有 1 升水。当他一口气使用了 N 次秘 籍后发现瓶子实在太多了,于是他决定保留不超过 K 个瓶子。规则是每次选择两个当前含 水量相同的瓶子进行合并,把一个瓶子的水全部倒进另一个瓶子,然后把空瓶砸碎。 显然在某些情况下 ZR 无法达到目标,比如 N=3,K=1。此时 ZR 会重新使用秘籍获得
一些新的瓶子(新瓶子容量无限,开始时有 1 升水),以达到目标。 现在 ZR想知道,除去一开始使用了N次秘籍,最少还需要使用多少次秘籍才能达到目
标?
输入格式:
一行两个正整数N,K(1<=N<=109,K<=1000)。
输出格式:
一个非负整数,表示最少需要买多少新瓶子。
输入样例:
3 1
输出样例:
1
数据规模:
对于 30%的数据,N<=3*105;
对于 100%的数据如题目。
题解
题目要求只能把水量相同的合并,于是可以贪心地把能合并的都合并,可以发现最终的水量是一些2的幂次,而这些数值的和也就是瓶子的数量N。那么最后剩下的瓶子个数就是N二进制中“1”的个数。如果“1”的个数小于等于K,那就满足要求了。如果大于K,假设N的二进制中最后一个“1”位置右数第K个,那么就添加2K-1个新瓶,直到使得N的二进制中“1”的个数减少到K个或以下。求某个十进制下的数字在二进制下有多少个“1”,可以不断减LowBit的方法来求。
假设x的二进制中最后一个“1”位置右数第y个LowBit(x) = 2y-1.
时间复杂度:O(K)
空间复杂度:O(1)
代码
#include<bits/stdc++.h>#define F(i,a,b) for( int i=(a);i<=(b);i++ )#define N 1001#define M 10001#define LL long long#define oo 0x7fffffffusing namespace std;LL read(){ LL f=1,s=0; char ch=getchar(); while( ch>'9' || ch<'0' ) { if( ch=='-' ) f=-1; ch=getchar(); } while( ch<='9' && ch>='0' ) { s=( s<<1 )+( s<<3 )+ch-'0'; ch=getchar(); } return f*s;}LL m,n,k,t;LL tot,ans;LL a[N],b[N];int fa,cnt;LL init(){ b[0]=1; F( i,1,oo ) { b[i]=b[i-1]*2; if( b[i]>=n ) break; } while( n>1 ) { a[cnt]=n%2; n/=2; cnt++; } a[cnt]=1;}LL cul( int x ){ a[x]+=1; while( a[x]==2 ) { a[x]=0; x++; a[x]++; } int mmax=max( x,cnt ); for( int i=mmax;i>=fa;i-- ) { if( a[i] ) t+=b[i]; } return t-m;} int main(){ freopen( "water.in","r",stdin ); freopen( "water.out","w",stdout ); n=read(); k=read(); m=n; init(); for( int i=cnt;i>=0;i-- ) { if( a[i] ) { tot++; if( tot==k+1 ) { ans=cul( fa ); break; } fa=i; } } cout<<ans<<endl; return 0;}
- 倒水(rms2017模拟2-1)* 【推理】
- 中位数(rms2017模拟3-1)*【推理】
- Beautiful string(rms2017模拟1-1)*【推理】
- 数位平方和(rms2017模拟14-2)* * *【推理】
- Prison (rms2017模拟1-3)* *【区间dp】
- 数 7(rms2017模拟14-1)* *【打表】
- Pots (模拟倒水)
- POJ 3414 Pots(模拟倒水)
- POJ 3414-Pots(BFS-模拟倒水)
- poj3414 pots 倒水模拟
- FZU 2202 犯罪嫌疑人(模拟、推理)
- Tower( rms模拟4-3 ) * *(推理)
- 【BFS】CODE[VS] 1226 倒水问题 (BFS+模拟)
- 宽度优先搜索模拟倒水
- 看守(rms模拟7-3)* * (推理)
- noip2003 侦探推理 终极模拟
- [NOIP模拟][数学推理]Math
- POJ 3414 Pots【bfs模拟倒水问题】
- 基于Qt的中国男足国家队“世亚预”小组赛出线分析
- 经验模态分解
- Python学习第一课
- nodejs爬虫参考
- python maximum recursion depth exceeded解决方式
- 倒水(rms2017模拟2-1)* 【推理】
- 169. Majority Element
- 执行HBase建表操作,每次创建表HRegionServer都会挂掉,而 HMaster还在!RetriesExhaustedException: Can't get the locations
- POJ2699 The Maximum Number of Strong Kings (maxflow)
- 由四个点求两条线段交点代码实现
- CentOS 7 下安装Chrome浏览器
- 二叉树遍历(已知先序、中序求后序)
- 深入学习APC
- dom解析