1元钱买一瓶啤酒。
2个空瓶换一瓶啤酒。
问10元能买几瓶啤酒?
再问n元能买几瓶啤酒?
答:第一次:10瓶
第二次:10个空瓶换5个啤酒
第三次:5个空瓶换2个啤酒,剩一个空瓶
第四次:算上上次的空瓶,3个空瓶换1个啤酒,剩一个空瓶
第五次:算上第四次的一个空瓶,2个空瓶换1个啤酒,最后剩1个空瓶。结束。
合计:10+5+2+1+1=19
于是我推测公式:
第一次:10
第二次:10*1/2
第三次:10*1/(2^2)
第四次:10*1/(2^3)
第五次:10*1/(2^4),四舍五入为1(这步出错)
于是我归纳为10(1+1/2+1/2^2+...+1/2^n)
取极限为10(2-1/2^n)
公式中n=4,结果为19.375,取整为19。
问:当9元可买多少瓶?
9元可买9(2-1/2^n)
取n=4,结果为17.4375,取整17。
这个n的取法在于初始金额m<2^n,即可。我当时面试时取的时m>2^n时,n取最大值。
增加m<2^n这个条件后,公式m(2-1/2^n)=2m-m/2^n<2m-1.
所以,买啤酒问题实际的解是2m-1,即10元为19瓶,9元为17瓶。
考官的解为2m-1,用数学归纳法证明。这个证明未考虑详细。故不讨论。
1 Console.WriteLine("买啤酒问题:一元买一瓶啤酒,两个空瓶换一瓶啤酒,问10元能买多少瓶啤酒?n元呢?请输入啤酒金额:"); 2 3 decimal money; 4 5 while (!Decimal.TryParse(Console.ReadLine(), out money)); 6 7 int count = 0;//次数 8 9 List<int> beerTotal = new List<int>(); 10 11 int full = (int)money;//啤酒 12 13 beerTotal.Add(full); 14 15 int empty = 0;//空瓶 16 17 while (true) 18 19 { 20 21 //喝酒,出来空瓶了 22 23 empty += full; 24 25 Console.WriteLine("第{0}次,买{1}瓶啤酒,有{2}瓶空瓶", count++, full, empty); 26 27 //空瓶2换1啤酒 28 29 full = empty / 2; 30 31 //使用列表记录对话瓶数,最后统计 32 33 beerTotal.Add(full); 34 35 //剩余多少个啤酒 36 37 empty = empty % 2; 38 39 //当换不了啤酒就结束吧。 40 41 if (full == 0) 42 43 break; 44 45 } 46 47 Console.WriteLine("{0}元可以买{1}瓶啤酒,哦顺便告诉你还剩{2}个空瓶", money, beerTotal.Sum(), empty); 48 49 Console.ReadKey();