免费注册 查看新帖 |

Chinaunix

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

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

论坛徽章:
27
CU大牛徽章
日期:2013-03-13 15:15:08CU大牛徽章
日期:2013-05-20 10:46:38CU大牛徽章
日期:2013-05-20 10:46:44CU大牛徽章
日期:2013-09-18 15:24:09CU大牛徽章
日期:2013-09-18 15:24:20CU大牛徽章
日期:2013-09-18 15:24:25CU大牛徽章
日期:2013-09-18 15:24:31CU大牛徽章
日期:2013-09-18 15:24:36CU大牛徽章
日期:2013-09-18 15:24:41CU大牛徽章
日期:2013-09-18 15:24:48CU大牛徽章
日期:2013-09-18 15:24:52处女座
日期:2013-09-27 17:45:43
41 [报告]
发表于 2011-03-28 11:52 |只看该作者
我的可以,
使用了递归
1.若是要找160的话
2.有100的话,先找100
3.这时需要找的就剩下60了,这时调用递归
4.递归第一次先找回50,剩下10,再找回5,发现最后还剩下5,找钱失败,这时回滚。
5.递归第二次先找回20,剩下40,再找回20,剩下20,再找回20,剩下0,返回成功
6.输出



  1. #例如:当售票机中有10c=>1, 20c=>3, 50c=>1。需要找60c,这个时候就要找1个50c的和1个10c的硬币,而不是3个20c的硬币。
  2. #再比如,当售票机中有5c=>1, 20c=>3, 50c=>1, 100c($1) => 1,需要找160c,这个时候也需要能正确找钱。
  3. #说的简单点,就是有个函数,你提供要找的钱当参数,返回值就是找出来的钱(例如:一个数组)。
  4. #所有的币值列表
  5. @coins=(   100,50,20,10,5,2,1);
  6. #每个币值对应的个数
  7. @coinnums=(  1, 1, 3, 0,1,0,0);

  8. #每个币值对应的个数
  9. @paybackCoins=();
  10. $paybackTotal=160;
  11. if(payback($paybackTotal)==0){
  12.         print join(",",@paybackCoins)."\n";
  13. }else{
  14.         print "payback $paybackTotal fail\n";
  15. }

  16. @coins=(   100,50,20,10,5,2,1);
  17. @coinnums=(  0, 1, 3, 1,0,0,0);
  18. @paybackCoins=();
  19. $paybackTotal=60;
  20. if(payback($paybackTotal)==0){
  21.         print join(",",@paybackCoins)."\n";
  22. }else{
  23.         print "payback $paybackTotal fail\n";
  24. }

  25. @paybackCoins=();
  26. $paybackTotal=55;
  27. if(payback($paybackTotal)==0){
  28.         print join(",",@paybackCoins)."\n";
  29. }else{
  30.         print "payback $paybackTotal fail\n";
  31. }

  32. sub payback{
  33.         my $payback=shift;
  34.         $coinslen=scalar(@coins);
  35.         my $i=0;
  36.         for($i=0;$i<$coinslen;$i++){
  37.                         if($coinnums[$i]>0){
  38.                                 my $coin=$coins[$i];
  39.                                
  40. #                                每次都从最大币值开始循环
  41.                                 if($payback >= $coin){
  42.                                         push(@paybackCoins,$coin);
  43.                                         $payback-=$coin;
  44.                                         $coinnums[$i]--;
  45.                                         if($payback<=0){
  46. #                                                剩下0时返回
  47.                                                 return 0;
  48.                                         }
  49. #                                        继续找剩下的钱
  50.                                         if(payback($payback)!=0){
  51. #                                                剩下的钱找不完时,回滚
  52.                                                 $rollbackCoin=pop(@paybackCoins);       
  53.                                                 $coinnums[$i]++;
  54.                                                 $payback+=$rollbackCoin;
  55.                                         }else{
  56. #                                                剩下的钱找完时,返回
  57.                                                 return 0;       
  58.                                         }
  59.                                 }
  60.                         }
  61.                 }
  62.         return 1;
  63. }
复制代码

论坛徽章:
0
42 [报告]
发表于 2011-03-28 13:18 |只看该作者
alabos 发表于 2011-03-25 16:34



   
这个代码不正确?

论坛徽章:
0
43 [报告]
发表于 2011-03-29 21:36 |只看该作者
进来看看题。

论坛徽章:
0
44 [报告]
发表于 2011-03-31 14:57 |只看该作者
c是澳大利亚钱币单位吗?看这个好费劲哦,直接写10块,20块这样好理解一些{:3_193:}

论坛徽章:
0
45 [报告]
发表于 2011-04-02 10:52 |只看该作者
这个需要在.net programming课程上做这样的题目嘛,这种题目应该放到算法或数据结构课上
“有大面值的货币就不找小面试的货币”
先对面值排序,贪心+递归枚举,不难,或者dp也可
其实就是个组合算法

论坛徽章:
0
46 [报告]
发表于 2011-04-05 20:35 |只看该作者

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
47 [报告]
发表于 2011-04-06 07:30 |只看该作者
c是澳大利亚钱币单位吗?看这个好费劲哦,直接写10块,20块这样好理解一些
chenjintao_ii 发表于 2011-03-31 14:57


"c" for cent
我照着那要求抄的,就全写成c了。。。

论坛徽章:
0
48 [报告]
发表于 2011-04-06 16:24 |只看该作者

  1. use strict;
  2. use warnings;

  3. sub find_share {
  4.         my ($target,$treasues)=@_;
  5.         return [] if $target==0;
  6.         return if $target<0 || @$treasues==0;
  7.         my ($first,@rest)=@$treasues;
  8.         my $solution = find_share($target-$first,\@rest);
  9.         return [$first,@$solution] if $solution;
  10.         return find_share($target,\@rest);
  11. }

  12. my @treasures=(100,50,20,20,20,10,5,5);
  13. my $target=160;
  14. my $solution = find_share($target,\@treasures);

  15. print "@$solution\n";
复制代码

论坛徽章:
0
49 [报告]
发表于 2011-04-07 09:29 |只看该作者
本帖最后由 mingxw 于 2011-04-07 09:33 编辑

改进一下:

  1. use strict;
  2. use warnings;

  3. use constant TREASUER_TYPES => 4;
  4. my @trea_list=(100,50,20,5);
  5. my $trea_num =[1,  2, 3,  1];

  6. sub find_share {
  7.         my ($target,$type,$nums)=@_;
  8.         return ([],$nums) if $target==0;
  9.         return (undef,$nums) if $type>=TREASUER_TYPES;
  10.         return find_share($target,$type+1,$nums) if $$nums[$type]<=0;
  11.        
  12.         my $first = $trea_list[$type];
  13.         return find_share($target,$type+1,$nums) if $target < $first;
  14.         $$nums[$type]--;
  15.         return ([$first],$nums) if $target == $first;
  16.         my $solution;       
  17.         ($solution,$nums) = find_share($target-$first,$type,$nums);
  18.         return ([$first,@$solution],$nums) if $solution;
  19.         $$nums[$type]++;
  20.         return find_share($target,$type+1,$nums);
  21. }

  22. my $target=160;
  23. my $solution;
  24. my $i=0;
  25. print "\nFind $target in ",join(", ",map {$trea_list[$i++]." x ".$_} @$trea_num),"\n";
  26. ($solution,$trea_num) = find_share($target,0,$trea_num);
  27. if($solution) {
  28.         $i=0;
  29.         print "\nFound : ",join(", ",@$solution);
  30.         print "\nTreasures remain: ",join(", ",map {$trea_list[$i++]." x ".$_} @$trea_num),"\n";
  31. }
复制代码

论坛徽章:
0
50 [报告]
发表于 2011-04-16 12:57 |只看该作者
回复 1# py


#!/usr/bin/perl -w

use strict;
use warnings;

my $fh;
if (not open($fh, "< ./pocket_money")) {
        print "Failed to open file [pocket_money]\n";
        exit(-1);
}
my @raw_data;
while (<$fh>) {
        chomp;
        my @tmp = split(/\s/, $_);
        if (2 != @tmp || $tmp[0] !~ /[0-9]+/ || $tmp[1] !~ /[0-9]+/) {
                print "Invalid numer\n";
                next;
        } else {
                push(@raw_data, [ @tmp ]);
        }
}
close($fh);
sub by_face_value {
        return $a->[0] <=> $b->[0];
}
my @pocket_money = reverse sort by_face_value @raw_data;

my $money;
my $err_cnt = 0;
while(1) {
        print "Enter money:";
        $money = <>;
        if ($money !~ /[0-9]+/) {
                print "Invalid money number\n";
                ++$err_cnt;
                exit(-1) if (5 == $err_cnt);
        } else {
                last;
        }
}

my @ret;
my @balance_pocket_money;
my $ok_flag = 0;
my $old_money = $money;
while (!$ok_flag) {
        my $quotient;
        my $remainder = $money;

        my $cur_face_value = shift(@pocket_money);
        if ($money < $cur_face_value->[0]) {

                push(@balance_pocket_money, $cur_face_value);
        } else {
                $quotient = int($money / $cur_face_value->[0]);
                $quotient = ($quotient > $cur_face_value->[1]) ? $cur_face_value->[1] : $quotient;
                $remainder = $money - $cur_face_value->[0] * $quotient;

                push(@ret, [ $cur_face_value->[0], $quotient ]);
                $cur_face_value->[1] = $cur_face_value->[1] - $quotient;
                push(@balance_pocket_money, $cur_face_value) if (0 < $cur_face_value->[1]);

                $money = $remainder;
        }

        if (0 == $remainder) {
                $ok_flag = 1;
                @pocket_money = (@balance_pocket_money, @pocket_money);
                print "找零组合:\n";
                foreach (@ret) {
                        print "面值:".$_->[0]."数量:".$_->[1]."\n";
                }
                print "----------------------------------------\n";
                print "剩余零钱:\n";
                foreach (@pocket_money) {
                        print "面值:".$_->[0]."数量:".$_->[1]."\n";
                }
        } else {
                while (0 == @pocket_money && 0 != @ret) {
                        my $ready_recall = 0;
                        $cur_face_value = pop(@ret);

                        for (my $idx = 0; $idx < @balance_pocket_money; ++$idx) {
                                if ($cur_face_value->[0] < $balance_pocket_money[$idx]->[0]) {
                                        next;
                                } elsif ($cur_face_value->[0] == $balance_pocket_money[$idx]->[0]) {
                                        --$cur_face_value->[1];
                                        $money += $cur_face_value->[0];
                                        if (0 < $cur_face_value->[1]) {
                                                push(@ret, $cur_face_value);
                                        }

                                        ++$balance_pocket_money[$idx]->[1];
                                        @pocket_money = splice(@balance_pocket_money, $idx + 1);

                                        $ready_recall = 1;
                                        last;
                                } else {
                                        --$cur_face_value->[1];
                                        $money += $cur_face_value->[0];
                                        if (0 < $cur_face_value->[1]) {
                                                push(@ret, $cur_face_value);
                                        }

                                        @pocket_money = splice(@balance_pocket_money, $idx);
                                        push(@balance_pocket_money, [ $cur_face_value->[0], 1 ]);

                                        $ready_recall = 1;
                                        last;
                                }
                        }
                        if (!$ready_recall) {
                                $money += $cur_face_value->[0] * $cur_face_value->[1];
                                push(@balance_pocket_money, $cur_face_value);
                        }
                }
                if ($money == $old_money) {
                        print "现有的零钱组合无法对[$money]找零:\n";
                        foreach (@balance_pocket_money) {
                                print "面值:".$_->[0]."数量:".$_->[1]."\n";
                        }
                        foreach (@pocket_money) {
                                print "面值:".$_->[0]."数量:".$_->[1]."\n";
                        }
                        last;
                }
        }
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP