免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: py
打印 上一主题 下一主题

给大家发一个澳大利亚研究生课程作业题 [复制链接]

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
21 [报告]
发表于 2011-03-25 14:55 |只看该作者
回复 15# guap514

恩,我就知道论坛上一定有高人。下班了,你的方法我还没仔细看,但非常简洁。
我基本上试了一下,没有问题。这代码太完美了。

我当时还写成了模块,80多行的代码,总觉得这事情被我搞复杂了,可又想不出更好的办法来。

我的办法是把找钱的过程想成一个树的遍历,先走大节点再走小节点。实现起来比你的这个要复杂多了。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
22 [报告]
发表于 2011-03-25 14:57 |只看该作者
这种问题还真不能仔细想,越想越麻烦,如果所有硬币都充足,按照取大不取小原则160美分的分配会是100+50+5*2,如果5美分硬币可能不充足,就要倒回去。。。
不想了,纠结

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
23 [报告]
发表于 2011-03-25 14:58 |只看该作者
回复  guap514


    好,递归好!
miniqq 发表于 2011-03-25 14:46


这个好像必须用递归,当时老师检查作业,他也没时间一个个的看了可能,就是粗略一看,没用递归就先减一分。因为不用递归的情况下,结果很大可能是错的。

论坛徽章:
2
白羊座
日期:2013-10-29 13:29:222015亚冠之全北现代
日期:2015-10-25 08:13:02
24 [报告]
发表于 2011-03-25 15:19 |只看该作者
回复 23# py


    我承认我写复杂了,但思路应该没问题.递归我看不是必须的吧!

论坛徽章:
0
25 [报告]
发表于 2011-03-25 16:34 |只看该作者
本帖最后由 alabos 于 2011-03-25 16:42 编辑

  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;

  4. my %store = qw{50 2  20 2 10 20 5 7 1  1000};

  5. my $need_change = 160;

  6. my $changed = &change($need_change);

  7. foreach  (reverse keys %$changed)
  8. {
  9.         print "$_: -->$changed->{$_}\n";
  10. }


  11. sub change ($)
  12. {
  13.         my $n_chage = shift;
  14.         my %changed;
  15.         my @units =reverse sort {$a <=> $b}  keys %store;

  16.         foreach  my $unit (@units)
  17.         {
  18.                 while ($store{$unit} > 0 && $n_chage - $unit >= 0)
  19.                 {
  20.                         $changed{$unit}++;
  21.                         $store{$unit}--;
  22.                         $n_chage -= $unit;
  23.                 }
  24.         }
  25.         return \%changed;
  26. }

  27. =head
  28. 在这里有个前提条件,就是,有足够的零钱去找。
  29. 如果不够的话,就需要加校验了。
  30. %store 生成一个钱的 hash 面值做为key ,
  31. key 的定义为系统处理的最小单位
  32. 处理办法, 通过排序,从大到小依次处理。
  33. =cut
复制代码

论坛徽章:
0
26 [报告]
发表于 2011-03-25 16:41 |只看该作者
如果题目指定了用递归,那没办法,必须得用!

不然,为啥不用简单的办法呢?

像这样,用个 while 不是一样简单

论坛徽章:
1
狮子座
日期:2013-12-16 16:09:24
27 [报告]
发表于 2011-03-25 20:24 |只看该作者
本帖最后由 ttcn_cu 于 2011-03-26 04:37 编辑

回复 1# py


    用递归写起来很短啊

  1. #!perl
  2. use strict;
  3. my @cc=(
  4.         [50=>99999],
  5.         [20=>99999],
  6.         [5=>99999]
  7. );
  8. my $input=1111830;
  9. my $count=0;
  10. my %re;
  11. sub change{
  12.         my @c=@{$_[0]};
  13.         my $t=$_[1];
  14.         while(1){
  15.                 $count++;
  16.                 $#c < 0 and return 0;
  17.                 $#c >=0 and do {
  18.                         my $h=$c[0]->[0];
  19.                         $c[0]->[1]--;
  20.                         shift @c if ($c[0]->[1] <= 0);
  21.                         $t>$h and do {
  22.                                 my $r=change(\@c,($t-$h));
  23.                                 $r == 1 and do {
  24.                                         $re{$h}++;
  25.                                         return 1;
  26.                                 };
  27.                                 $r == 0 and do {
  28.                                         shift @c;
  29.                                         next;
  30.                                 };
  31.                         };
  32.                         $h==$t and do {
  33.                                 $re{$h}++;
  34.                                 return 1;
  35.                         };
  36.                         return 0;
  37.                 };
  38.         }
  39. }
  40. print "$input=\n";
  41. change(\@cc,$input) or print "not found";
  42. print "$_=>$re{$_}\n" for keys %re;
  43. print "\nloop count=$count\n";


复制代码
要是Perl能像C一样支持宏替换把and 换成 箭头之类的符号看起来就舒服
貌似和15楼原理一样,展开了一下

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
28 [报告]
发表于 2011-03-25 21:18 |只看该作者
如果题目指定了用递归,那没办法,必须得用!

不然,为啥不用简单的办法呢?

像这样,用个 while 不是 ...
alabos 发表于 2011-03-25 16:41


没有,老师从没说过一定要用递归,只是,没有用递归的人,在测试过老师给出的那几个例子的时候都多少出了问题。

我觉得肯定还是可以不用递归成功做出来的,只是递归写起来很清楚简介

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
29 [报告]
发表于 2011-03-25 21:56 |只看该作者
回复 27# ttcn_cu

对,递归就是效率低,写起来短。不过也要注意,当时很多人都用递归,但是很多人程序都有错误。等周一上班了我再试试大家的程序。

论坛徽章:
1
狮子座
日期:2013-12-16 16:09:24
30 [报告]
发表于 2011-03-25 22:23 |只看该作者
本帖最后由 ttcn_cu 于 2011-03-26 06:54 编辑

回复 29# py


    不递归

  1. #!perl -w
  2. use strict;
  3. my @original=(
  4.     [100=>11111111111],
  5.     [20=>11111111111],
  6.     [5=>11111]
  7. ); #原始存的货币数目
  8. my $input=2175;
  9. my $count=0;
  10. my @backup=map {
  11.     [
  12.         $_->[0],
  13.         $a=int($input/$_->[0])<$_->[1]?int($input/$_->[0]):$_->[1],
  14.         $_->[0]*$a
  15.     ]
  16. } @original;  #优化备份
  17. my @worker = map { [$_->[0],$_->[1]]} @backup;
  18. $_->[2]=$_->[0]*$_->[1] for @worker;
  19. BIG:
  20. while (1){
  21.     $count++;
  22.     my $sum=0;
  23.     for (0..$#worker-1){
  24.         $sum+=$worker[$_]->[2];
  25.     }
  26.     $sum+=$worker[$#worker]->[0]*$worker[$#worker]->[1];
  27.     my $delta=$sum-$input;
  28.     if ($delta==0){
  29.         print "$sum = ";
  30.         print join " + ", map { "$_->[0] * $_->[1]" } grep {$_->[1] } @worker;
  31.         last BIG;
  32.     }
  33.     for my $idx (reverse 0..$#worker){
  34.         next if $worker[$idx]->[1]==0;
  35.         if ($idx!=$#worker){
  36.             $worker[$idx]->[1]--;
  37.         }
  38.         else{ #最小面额使用贪婪
  39.             $worker[$idx]->[1] =
  40.                 ($delta <= $worker[$idx]->[0]||int($delta/$worker[$idx]->[0])>$worker[$idx]->[1])
  41.                 ?
  42.                     0
  43.                 :
  44.                     $worker[$idx]->[1] - int($delta/$worker[$idx]->[0]);
  45.         }
  46.         $worker[$idx]->[2] = $worker[$idx]->[0] * $worker[$idx]->[1];
  47.         @worker[($idx+1)..$#worker] = map { [$_->[0],$_->[1],$_->[2]] } @backup[($idx+1)..$#worker];
  48.         next BIG;
  49.     }
  50.     print "not found";
  51.     last BIG;
  52. }
  53. print "\nloop count=$count";

复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP