免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 21045 | 回复: 53
打印 上一主题 下一主题

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

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-03-25 07:31 |只看该作者 |正序浏览
本帖最后由 py 于 2011-03-25 09:40 编辑

题目:投币自动售票程序
要求: 找钱原则“有大面值的货币就不找小面试的货币”

例如:当售票机中有10c=>1, 20c=>3, 50c=>1。需要找60c,这个时候就要找1个50c的和1个10c的硬币,而不是3个20c的硬币。
再比如,当售票机中有5c=>1, 20c=>3, 50c=>1, 100c($1) => 1,需要找160c,这个时候也需要能正确找钱。
说的简单点,就是有个函数,你提供要找的钱当参数,返回值就是找出来的钱(例如:一个数组)。

此题是澳大利亚研究生课程中.NET Programming课的结课作业,老师给了2周的时间,开卷完成。

最近收拾屋子的时候又看到了这个作业,发出来,看看大家有没有什么精妙的办法。

论坛徽章:
0
54 [报告]
发表于 2011-04-20 20:29 |只看该作者
就是以下的算式吧:
m=100x+50y+20z+10a+5b
m是余额,按面额从大到小顺序
第一步    x=m /100 , x是需要100面值的张数.在和钱箱中的该面值的钱的数量比较,根据结果得到x的值(x大于等于零),
第二步    m1=m-100x , 同样的用m1处理其它面额的,递归算法.

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
53 [报告]
发表于 2011-04-18 09:55 |只看该作者
.NET Programming?这个不用两周吧?
2gua 发表于 2011-04-17 11:10

这门课是学一个学期的,一周一节课,一共学半年。
这个作业最后老师给了1个半月。结果还是绝大多数人做不出。
那门课其实是学习C#的基础课,很多选那门课的人接触编程并不多,再加上到期末了,还有其他课需要忙,所以老师一般会给比较宽裕的时间。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
52 [报告]
发表于 2011-04-18 09:49 |只看该作者
回复 50# vgra
可以看看15楼的回复。。。。。。个人感觉是最好的答案
或是use Ticketmaster;我把它写成模块了

论坛徽章:
0
51 [报告]
发表于 2011-04-17 11:10 |只看该作者
.NET Programming?这个不用两周吧?

论坛徽章:
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;
                }
        }
}

论坛徽章:
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
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";
复制代码

论坛徽章:
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
46 [报告]
发表于 2011-04-05 20:35 |只看该作者
  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP