罐子和硬币-c#求解-英雄会在线编程题目

       各位朋友新年好!过完年后来csdn逛逛,发现上了新的编程题目,一道罐子和硬币,一道搜索排序。今天就先说罐子和硬币的题目。先看题目:

罐子和硬币
  • 发布公司:
  • 有 效 期:
  • 赛    区:
  • CSDN                
  • 2014-01-242014-03-02
  • 北京
  • 难 度 等 级:
  • 答 题 时 长:
  • 编程语言要求:
  • 120分钟
  • C C++ Java C#                 
题目详情

有n个罐子,有k个硬币,每个罐子可以容纳任意数量的硬币。罐子是不透明的,起初你可以随机把这k个硬币任意放在罐子里。然后罐子被打乱顺序,你从外表无法区别罐子。最后罐子被编上号1-n。你有p次机会,每次你可以选择某个罐子,如果该罐子里有硬币,则你可以得到1个(你不可以知道该罐子里有多少硬币),如果该罐子是空的,你得不到任何硬币。你最终要得到至少c枚硬币,我们的问题是给定n,k,c,求出最少的p,存在一种你最初放硬币的方式,无论罐子如何被打乱顺序,你都能p次机会内获得至少c个硬币。

输入n,k,c (0 < n <=1000000, 0 < c <= k <=1000000)。

输出,最小的p值。

例如n = 3, k = 6, c = 4。 你可以把每个罐子放入两个硬币,这样得到4次机会可以得到4个硬币,输出4。

 

       题目看起来挺简单的,仔细想想似乎又不简单。

分析:这道题其实对编程考察的不多,主要是考察思维方式。即你如何放硬币,如何取硬币的方式。

我最开始是这么想的,把硬币平均放在每个瓶子里面,取硬币的时候,每个瓶子轮流取。直到取到c个,问题是,平均放,可能有些瓶子装的少一个,即k%n !=0,比如说n=10,k=28,那么每个瓶子装2个,还有8个瓶子多装一个,装了3个,如果我们要取25个,即c=25,前20个比较好取,后5个怎么取?按照这种装法,至少还要取2+5=7次,因为有2次你可能摸到的是空瓶子。但是这种取法是不是最优了?如果k=21,c=21了?那不是要取20+1+9=30次。显然,我们可以吧最后一个瓶子里面的两个金币放到前面不是3个金币的瓶子里面,这样取得次数就少于30,再依次移动最后一个瓶子里面的金币到前面不是3个金币的瓶子,使其金币数达到3个,我们发现,次数都会逐渐减少,直到不能移动为止。

 

现在回过头来看下,这道题基本上思路就比较清晰了。

步骤

1、首先将硬币平均分配到每个瓶子,如果k%n==0,那么取c个硬币只需要c次。

2、如果k%n  !=0  ,那么我们就要考虑要取多少个硬币,如果c<Math.Floor(k/n)*n,很显然平均分配硬币,然后轮流取每个瓶子,c次就可以取到了。

3、当k%n  !=0 时,而c>=Math.Floor(k/n)*n的时候,也就是我们上面分析的,这个时候就要从最后一个瓶子开始抽取硬币,补充到前面没有装满的瓶子。

这个如果用画图的方式展现,就很好理解了:

瓶1,瓶2,............瓶n

1,1,1,1,。。。,1

1,1,1,。。。。。1

。。。。。。。。

1,1,。。,0,0.。0

首先平均分配,发现后面还有n-k%n个瓶子少一个硬币,因此,吧最后一个瓶子里面的硬币拿出来补充这(n-k%n +1)个瓶子里,不足,就再下一个瓶子里的硬币,最后形成了这样一个图:

瓶1,瓶2,............瓶n

1,1,1,1,。。。1...0

1,1,1,。。。。1...0

。。。。。。。1...0

1,1,。。,   1,0...0

其中行数row = k / n + 1;

而这n个瓶子中有col=k/row 个瓶装的一样多,剩下的瓶子,要么全为空,或者有一个吧剩下的硬币装进去了,很显然,这时候要取c个硬币,最差的情况p= n - col + c;

ok,到此分析完毕了,也就是三种情况,代码也非常的少,大概十多行吧,提交,没问题,通过。

 

 

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值