博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
2017广东工业大学程序设计竞赛 E倒水(Water)
阅读量:6227 次
发布时间:2019-06-21

本文共 3064 字,大约阅读时间需要 10 分钟。

原题链接:

 

Problem E: 倒水(Water)

Description

 

一天,CC买了N个容量可以认为是无限大的瓶子,开始时每个瓶子里有1升水。接着~~CC发现瓶子实在太多了,于是他决定保留不超过K个瓶子。每次他选择两个当前含水量相同的瓶子,把一个瓶子的水全部倒进另一个里,然后把空瓶丢弃。(不能丢弃有水的瓶子)

显然在某些情况下CC无法达到目标,比如N=3,K=1。此时CC会重新买一些新的瓶子(新瓶子容量无限,开始时有1升水),以到达目标。

现在CC想知道,最少需要买多少新瓶子才能达到目标呢?

Input

 

第一行一个整数T,表示有T组数据。

接着T行,每行两个正整数, N,K(1<=N<=10^9K<=1000)

 

Output

 

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

Sample Input

3 3 1 13 2 1000000 5

Sample Output

1 3 15808
 
 
***********************************************************************************************

题意:

  有n个瓶子,每个瓶子里有1升的水,当两个瓶子的水一样的时候,可以把2个瓶子合到一起,给了个k,还要加多少个瓶子才能够使总的瓶子合成不超过k个瓶子。

题解:

  1) 我一开始想这一题毫无疑问是贪心,当出现奇数瓶子的时候就补上当前瓶子里的水(因为瓶子里的水就是n个1升水的个数)。然后发现第3个sample不对,算多了。

    然后就突然想到,当出现奇数个瓶子的时候,把那一个瓶子拿到一边去(记录起来),剩下的两两合并。画了一下相对一种ans有减少。但是第3个样例不对。

    最后发现我一开始把瓶子压到小于k的时候就停止了。其实还可以继续往下压缩,直到要缩到最后一个。(现在只有一个瓶子了)

    在从记录起来的瓶子里从大到小补全k-1个瓶子(有k-1个瓶子了),把记录里面剩下的瓶子通过补充瓶子最后合并成一个瓶子。

    

1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 using namespace std;13 #define pb push_back14 #define mp make_pair15 #define mset(a, b) memset((a), (b), sizeof(a))16 typedef long long LL;17 const int inf = 0x3f3f3f3f;18 const int maxn = 1000+10;19 vector
hehe;20 int solve(int n, int water)21 {22 if(n==1) return water;23 if(n%2==0){24 solve(n/2, water*2);25 }26 else{27 hehe.pb(water);28 solve((n-1)/2, water*2);29 }30 }31 int main()32 {33 int T;34 cin >> T;35 while(T--)36 {37 int N, K;38 cin >> N >> K;39 if(N<=K)40 cout << "0" << endl;41 else42 {43 int endnum=solve(N, 1);44 if(hehe.empty()){45 cout << "0" << endl;46 }47 else{48 int ans =0;49 if(K==1){50 ans = endnum;51 for(int i=0;i
题解一

 

  2)官方题解:

    

    看了一下题解,发现题解十分的巧妙。灵活运用 x&(-x) 和 n&=(n-1) ;

    简单讲一下 x&(-x)是求 x 2进制时最低位的1的2^k的值,而n&=(n-1)是用来求 n 里有多少个1。

1 int cnt(int n){
//计算n中有多少个12 int num=0;3 while(n>0){4 num++;5 n&=(n-1);6 }7 return num;8 }
求有多少个1

 

    贴上具体代码

    

1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 using namespace std;13 #define pb push_back14 #define mp make_pair15 #define ms(a, b) memset((a), (b), sizeof(a))16 //#define LOCAL17 typedef long long LL;18 const int inf = 0x3f3f3f3f;19 const int maxn = 10000+10;20 const int mod = 1e9+7;21 int cnt(int n){ //计算n中有多少个122 int num=0;23 while(n>0){24 num++;25 n&=(n-1);26 }27 return num;28 }29 int lowbit(int x){30 return x&(-x);31 }32 int main()33 {34 #ifdef LOCAL35 freopen("input.txt" , "r", stdin);36 #endif // LOCAL37 int T, n, k;38 cin >> T;39 while(T--){40 cin >> n >> k;41 int ans =0;42 while(cnt(n)>k){43 ans += lowbit(n);44 n+=lowbit(n);//补上lowbit(n)个瓶子,就会进位。45 }46 cout << ans << endl;47 }48 return 0;49 }
题解二

 

果然我还是太菜了XD。

 

    

 

转载于:https://www.cnblogs.com/denghaiquan/p/6667015.html

你可能感兴趣的文章
有关于认证和加密
查看>>
深入浅出Git教程(转载)
查看>>
[转载]MySQL5.6 PERFORMANCE_SCHEMA 说明
查看>>
max_allowed_packet引起同步报错处理
查看>>
006 复杂的数据类型&函数(方法)
查看>>
javascript:getElementsByName td name
查看>>
ASP.NET连接SQL、Access、Excel数据库(二)——连接实例
查看>>
FreeRTOS 特性简介
查看>>
Linux--前后端分离部署
查看>>
java阶段学习目标
查看>>
Azure IoT 技术研究系列2
查看>>
day24-3-2子类继承构造方法
查看>>
我们一起学习WCF 第五篇数据协定和消息协定
查看>>
Linux 与 Windows 文件互传(VMWare)
查看>>
Python学习笔记八 面向对象高级编程(一)
查看>>
Oracle内置函数
查看>>
UVA 1645 Count
查看>>
贪吃蛇程序
查看>>
poj 1419 Graph Coloring
查看>>
node的安装及其运用及相关配置
查看>>