摘要:【原文地址】 http://codingdojo.org/cgi-bin/wiki.pl?KataPotter
【题目描述】
从前有一套5册的系列书,是关于一个名叫“Harry”的英国英雄的(起码在该问题出现时还只有5本,但之后又出了无数本)。全世界的儿童都认为他非常了不起,自然,出版商也这么认为。作为一种对全人类的无比慷慨的姿态,(以及为了提高销量),出版商制定了下述标价模型,来充分利用Harry的魔力:
5册书的任何1本的价格为8欧元。但,假如你从该系列购买2本不同的书的话,这2本书你可以得到5%的折扣。如果你购买3本不同的书,你可以得到10%的折扣。如果你购买4本不同的书,你可以得到20%的折扣。如果你购买整个系列,你可以得到25%的折扣。
注意,如果你购买4本书,其中3本书是不同的,那么对那3本书,你可以得到10%的折扣,但第4本的价格仍然是原价-8欧元。
Potter狂热席卷全国,各地少年儿童的父母装着满车的Potter书在柜台外排起了长队。。。你的任务是写段代码,计算每个购物车的金额,尽可能给与最大折扣。
譬如,这个购物车里的图书算多少钱?
第一册书有2本第二册书有2本第三册书有2本第四册书有1本第五册书有1本
(答案是 51.20 欧元)。
【提示】
一开始你也许会发现这个题目很容易,你可以从0本书,1本书,2本同样的书,2本不同的书。。。。等等购物车例子开始,迈小步子前进,逐步引进复杂性。
然后,当你坐下来,计算上面的购物车例子该算多少钱时,你会发现其中的曲折。金额不是5*8*0.75+3*8*0.90,实际上是4*8*0.8+4*8*0.8。这个题目的验收测试并没有错误,诀窍是你该如何编程来决定2份4册的书比1份3册的书和1份5册的书便宜。
你也许需要引进一些优化算法,但不用太费劲,按部就班地解决问题,相信自己在新的需求来临时,能进行概括,改进方案。
【推荐的测试例子】(是以Ruby语言写的,但应该很容易转换成C#代码的):def testBasics
assert_equal(0, price([]))
assert_equal(8, price([0]))
assert_equal(8, price([1]))
assert_equal(8, price([2]))
assert_equal(8, price([3]))
assert_equal(8, price([4]))
assert_equal(8 * 2, price([0, 0]))
assert_equal(8 * 3, price([1, 1, 1]))
end
def testSimpleDiscounts
assert_equal(8 * 2 * 0.95, price([0, 1]))
assert_equal(8 * 3 * 0.9, price([0, 2, 4]))
assert_equal(8 * 4 * 0.8, price([0, 1, 2, 4]))
assert_equal(8 * 5 * 0.75, price([0, 1, 2, 3, 4]))
end
def testSeveralDiscounts
assert_equal(8 + (8 * 2 * 0.95), price([0, 0, 1]))
assert_equal(2 * (8 * 2 * 0.95), price([0, 0, 1, 1]))
......[
阅读全文]