通过自动取款机打给我一些现金


26

任务很简单。给我一些1000500100注意事项。

怎么样 ?你可能会问。不用担心,因为附近有自动取款机可以接收您的信用卡,因此无需抢劫银行。但是您的信用额度仅够完成任务,因此您在提款时必须格外小心。

挑战

鉴于数量1000500以及100所需音符,计算得到至少那些许多笔记所需的特定取款。在每次提款中,ATM均可根据以下规则吐出每张钞票:

  • 提取的金额(A)小于5000
    • 如果为A%1000 == 0,则ATM吐出1个500便笺,5个100便笺和其余1000便笺
    • 否则A%500 == 0,ATM会吐出5张100钞票,其余1000钞票
    • 否则A%1000 < 500,自动柜员机会吐出floor(A/1000) 1000纸币和休息100纸币
    • 否则A%1000 > 500,ATM会吐出floor(A/1000) 1000钞票,1 500和休息100钞票
  • 提款金额大于等于 5000
    • 如果为A%1000 == 0,则ATM吐出2个500便笺和其余1000便笺
    • 否则,如果A%500 == 0ATM吐出1张500便笺和其余1000便笺
    • 否则A%1000 < 500,自动柜员机会吐出floor(A/1000) 1000纸币和休息100纸币
    • 否则A%1000 > 500,ATM会吐出floor(A/1000) 1000钞票,1 500和休息100钞票

为了澄清起见,以下是一张完整的纸币表,其中列出了所有可能的最高金额7000(您可以提取更多,但此后模式不会改变)。顺序是<1000> <500> <100>

 100 => 0 0 1                  2500 => 2 0 5                   4800 => 4 1 3
 200 => 0 0 2                  2600 => 2 1 1                   4900 => 4 1 4
 300 => 0 0 3                  2700 => 2 1 2                   5000 => 4 2 0
 400 => 0 0 4                  2800 => 2 1 3                   5100 => 5 0 1
 500 => 0 0 5                  2900 => 2 1 4                   5200 => 5 0 2
 600 => 0 1 1                  3000 => 2 1 5                   5300 => 5 0 3
 700 => 0 1 2                  3100 => 3 0 1                   5400 => 5 0 4
 800 => 0 1 3                  3200 => 3 0 2                   5500 => 5 1 0
 900 => 0 1 4                  3300 => 3 0 3                   5600 => 5 1 1
1000 => 0 1 5                  3400 => 3 0 4                   5700 => 5 1 2
1100 => 1 0 1                  3500 => 3 0 5                   5800 => 5 1 3
1200 => 1 0 2                  3600 => 3 1 1                   5900 => 5 1 4
1300 => 1 0 3                  3700 => 3 1 2                   6000 => 5 2 0
1400 => 1 0 4                  3800 => 3 1 3                   6100 => 6 0 1
1500 => 1 0 5                  3900 => 3 1 4                   6200 => 6 0 2
1600 => 1 1 1                  4000 => 3 1 5                   6300 => 6 0 3
1700 => 1 1 2                  4100 => 4 0 1                   6400 => 6 0 4
1800 => 1 1 3                  4200 => 4 0 2                   6500 => 6 1 0
1900 => 1 1 4                  4300 => 4 0 3                   6600 => 6 1 1
2000 => 1 1 5                  4400 => 4 0 4                   6700 => 6 1 2
2100 => 2 0 1                  4500 => 4 0 5                   6800 => 6 1 3
2200 => 2 0 2                  4600 => 4 1 1                   6900 => 6 1 4
2300 => 2 0 3                  4700 => 4 1 2                   7000 => 6 2 0
2400 => 2 0 4

马丁提供的清单

赶上

由于信用卡中的信用额度就足够了,因此您需要确保在每次提款中提取总金额对于给定的输入/需要的票据而言是最小的。

输入项

输入可以任何有利的格式输入三个数字1000,分别500与价值所需的票据数量和100。不一定按此顺序。

输出量

输出是每笔交易中要撤回的金额,以新行分隔。

例子

输入(格式<1000> <500> <100>):

3 4 1

输出:

600
600
600
3600

再多一点:

7 2 5
5000
3500

1 2 3
600
1700

21 14 2
600
600
600
1600
5000
5000
5000
5000
5000

假设条件

  • 您可以假设ATM上的每个数量的钞票数量都无限。
  • 您可能还假设可以进行任意数量的交易。
  • 此外,某些输入值的解决方案可能不是唯一的,因此您可以输出任何一种解决方案,只要它们满足最小数量和最小注释要求的条件即可。

像往常一样,您可以编写一个完整的程序来读取通过STDIN / ARGV的输入,然后将输出打印到STDOUT或一个通过参数获取输入的函数,然后返回一个与数量相对应的整数列表或一个用新行分隔数量的字符串。

这是代码高尔夫球,因此以字节为单位的最短代码获胜。


确实是@nutki。编辑。
Optimizer

有速度限制吗?最后一个测试用例是否应该21 14 2在合理的时间内完成?
雅库布2015年

1
@Jakube在合理的时间内-是的(例如少于5-6小时)。但是因此,没有限制,因为这是代码高尔夫球。
Optimizer

那么,如果我提款0,会给我5张100张钞票吗?
AJMansfield

@AJMansfield当然不是。您不能提取0金额
优化程序

Answers:


7

JavaScript中,184 148

function g(a,b,c){x=[];while(a>0||b>0||c>0){i=b<3||a<4?a:4;a-=i;if(i>3&&b>1){b-=2;i++}else{i+=(c--<b&&i>4?0:.1)+(b-->0?.5:0)}x.push(i*1e3)}return x}

http://jsfiddle.net/vuyv4r0p/2/

返回对应于提款金额的整数列表


尝试g(5,1,1)。一个更好的解决方案:5600
jimmy23013 2015年

应该立即修复
hoffmale 2015年

g(5,1,0),解决方案:5500
jimmy23013 2015年

现在也应该修复^^感谢您指出,我一定太困了
hoffmale15年

g(5,2,0),解决方案:6000
jimmy23013

1

Perl 5:223

编辑

该解决方案是在错误假设7K是ATM限制的情况下完成的。实际上,这使该任务变得更加有趣,因为它需要动态编程(移动模式非常有规律,但是硬编码它可能比我现场计算的时间更长)。尽可能多的移动方式都很规则,以至于很难对其进行硬编码。我不知道@hoffmale的解决方案现在是否正确,但这将在这些行中。因此,可悲的是,这将是另一项任务,首先有人要提供解决方案,然后将其移植到高尔夫语言中以获得胜利。

比原始解决方案要慢一些(但对于低于100的参数仍然不到一秒)。

#!perl -pa
$c{0,0}=$f=($a,$b,$c)=@F;for$i(0..$b){for$j(0..$a){
/.(?=.$)/>($n=$c{$i-$`,$j-$'})||${$r=\$c{$i,$j}}<($x=$n+$&)&&$$r
or$f=$$r="$x $n".($'.$&+5*$`)."00
"for 204..206,105,106,11..15,110..114}}$_=$f."100
"x($c-$f+3);s/.*\b3//

更快的259解决方案。

#!perl -pa
$c{0,0}=($a,$b,$c)=@F;for$i(0..$b){for$j(0..$a){
/\B./<($%=$c{$i-$&,$j-$'}+$`)&&(!${$r=\$c{$i,$j}}||$$r>$%)and$d{$i,$j}=$_,$$r=$%for
qw/024 025 026 015 016/,101..105,110..114}}
$d{$b,$a}=~/\B./,$c-=$`,$b-=$&,$a-=$',print$'.$`+5*$&,"00
"while$a+$b;$_="100
"x$c

使用STDIN:

$perl atm.pl <<<"21 14 2"
5000
5000
5000
5000
5000
600
600
600
1600

尝试10 0 0。更好的解决方案:10100
jimmy23013 2015年

@ user23013糟糕,我误解了这个问题。我以为7K是最高金额:(我希望我将能够解决它。
nutki
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.