【求一高效算法,感兴趣的朋友可以来试试,高分】解决方案整理系列二

探讨了不同数量的礼物如何公平分配给固定数量的小朋友,确保每人获得的礼物数量尽可能平均,同时提出了几种实现方案,包括Java、Delphi等语言的示例代码。

问题: (帖子路径:http://topic.youkuaiyun.com/u/20091027/09/db4cd117-bfbe-491f-bcb8-d54ee08c0787.html
求一个高效算法:
有100名小朋友,
现在有一堆礼物
若是礼物数量小于100,比如为81,则这个81份礼物随机分配给小朋友,但要确保是一个人只能拿到一份礼物;

若是礼物数量大于100,
比如为115,则每个人至少有一份礼物,部分人有两份礼物,但没人拿到两份份以上的礼物;
比如为245,则每个人至少有两份礼物,部分人有三份礼物,但没人拿到三分份以上的礼物;

就是这个思路,这里声明不是大学老师布置的题目啊,是自己工作中一个抽象出来的问题,
希望得到大家的思路,,参与者,高分重谢!
也是个大家交流的机会


这个帖子让我感慨,我们csdn论坛中卧虎藏龙,真的很佩服,

本次系列一,把主要的解决思想整理一下

地址:http://blog.youkuaiyun.com/yinyuan1987/archive/2009/10/30/4748636.aspx

系列二,把大家使用不同的解决方法或实例提出来共享一下

地址:http://blog.youkuaiyun.com/yinyuan1987/archive/2009/10/30/4748671.aspx

系列三,把大家对性能方面思路提出来共享一下

地址:http://blog.youkuaiyun.com/yinyuan1987/archive/2009/10/30/4748715.aspx

更有58sxx_tt朋友用数据库实现:很惊艳!

给大家贴段数据库实现方法

--gn:礼物数 --pn:人数 --v_str:循环时每次取的人的编号 --result:循环结束时被选中的人的编号的串,每个编号用逗号分割 if mod(gn,pn) <> 0 then dbms_output.put_line('---礼物数不是人数的倍数-----'); if floor(gn/pn) < 1 then --当礼物数少于人数 v_sql := 'select a from (select a from (select level a from dual connect by level <='||pn||') order by dbms_random.value ) where rownum <='||gn; elsif floor(gn/pn) >= 1 then --当礼物数大于人数 v_sql := 'select a from (select a from (select level a from dual connect by level <='||pn||') order by dbms_random.value ) where rownum <='||mod(gn,pn); end if; open v_cur for v_sql; loop fetch v_cur into v_str; exit when v_cur%notfound; result := v_str||','||result; end loop; close v_cur; if floor(gn/pn) < 1 then dbms_output.put_line('---the gainers are '||result); elsif floor(gn/pn) >= 1 then dbms_output.put_line(result||' can gain '||ceil(gn/pn)||' gift, others can gain '||floor(gn/pn)||' gift!!!'); end if; elsif mod(gn,pn) = 0 then --当礼物数是人数的整数倍 dbms_output.put_line('----everyone can receive '||gn/pn||' gift!!'); end if;

78楼朋友feihua317Java写出了测试代码,并且数据量大小,数据库执行时间的演示:

The following is not the best solution and the cost time is 15-31 ms.

package org.guangguang; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class Play { public static void main(String[] args) { long numberOfGifts = 155; int students = 100; long startTime = System.currentTimeMillis(); Map<Integer, Long> results = new HashMap<Integer, Long>(students); List<Integer> luckyStudents = new ArrayList<Integer>(students); for(int i=1; i<=100; i++){ // First every student gets gift in average. results.put(i, numberOfGifts/students); luckyStudents.add(i); } for(int restGifts=(int)(numberOfGifts%students); restGifts>0; restGifts--){ int luckyNo = (int)(luckyStudents.size() * Math.random()); // increase the gain of the lucky student Integer luckyStudent = luckyStudents.get(luckyNo); results.put(luckyStudent, results.get(luckyStudent) + 1); // remove him from the lucky list, and continue to find lucky student. luckyStudents.remove(luckyStudent); } for(int i=1; i<=100; i++){ // Print the results System.out.println("The student " + i + " get gifts: " + results.get(i)); } System.out.println("Cost Time(ms): " + (System.currentTimeMillis()-startTime)); }

如果小朋友数量只有100的话,代码对性能的影响很小,要礼物数量和小朋友数量都很多,这样才能看出代码性能。我修改了一下,把礼物数量设置到1亿多,小朋友1万个,耗时300多毫秒。 public static void main(String[] args) { long numberOfGifts = 123456789; int students = 10000; long startTime = System.currentTimeMillis(); Map<Integer, Long> results = new HashMap<Integer, Long>(students); List<Integer> luckyStudents = new ArrayList<Integer>(students); long average = numberOfGifts/students; for(int i=1; i<=students; i++){ // First every student gets gift in average. results.put(i, average); luckyStudents.add(i); } for(int restGifts=(int)(numberOfGifts%students); restGifts>0; restGifts--){ int luckyNo = (int)(luckyStudents.size() * Math.random()); // increase the gain of the lucky student Integer luckyStudent = luckyStudents.get(luckyNo); results.put(luckyStudent, results.get(luckyStudent) + 1); // remove him from the lucky list, and continue to find lucky student. luckyStudents.remove(luckyStudent); } for(int i=1; i<=100; i++){ // Print the results System.out.println("The student " + i + " get gifts: " + results.get(i)); } System.out.println("Cost Time(ms): " + (System.currentTimeMillis()-startTime)); }

92楼朋友fall513DELPHI实现的:

楼上的太多了
我也就懒得看了
我来说说我的想法吧(首先声明我不会JAVA,而且只用DELPHI实现过)
aa: array [1..99] of integer; i :integer; j :integer; swap: integer; for i := 1 to 99 do aa[i] := i; for i := 1 to 99 do begin j := 1 + random(99);//delphi中RANDOM是从0开始取不到99的,所以要加1 swap := aa[i]; aa[i] := j; aa[j] := swap; end;

之后看你要多少个数就取前几个好了
为了保证每次随机顺序不一样可以初始化随机因子

代码很简单,但是可能比较难理解

当然还有C/C++ ,C#的解决实例,大家可以参考帖子,希望对大家有帮助

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值