题目描述
有这样一道智力题:“某商店规定:三个空汽水瓶可以换一瓶汽水。小张手上有十个空汽水瓶,她最多可以换多少瓶汽水喝?”答案是5瓶,方法如下:先用9个空瓶子换3瓶汽水,喝掉3瓶满的,喝完以后4个空瓶子,用3个再换一瓶,喝掉这瓶满的,这时候剩2个空瓶子。然后你让老板先借给你一瓶汽水,喝掉这瓶满的,喝完以后用3个空瓶子换一瓶满的还给老板。如果小张手上有n个空汽水瓶,最多可以换多少瓶汽水喝?
解题思路
假如有n个空水瓶,那么n div 3 = a ... b,就是说n个水瓶直接能够换到的汽水为a个,那么剩下b个空瓶子不能够换汽水,加上喝完a瓶汽水剩下a个空瓶。现在又剩下a+b个空瓶,做下一次交换。因此这是一个递归问题。注意到当剩下两个瓶子时可以“借”一瓶汽水得到3个空瓶来抵账,递归的结束条件有两个。
我的解法(C++)
#include <iostream> #include <vector> using namespace std ; auto SWAPBOTTLENUM = 3 ;//3个konp int solution(int emptyBottles) { if(emptyBottles == SWAPBOTTLENUM-1) return 1 ; else if(emptyBottles < SWAPBOTTLENUM-1) return 0 ; int drinked = 0 ; int rest = 0 ; drinked = emptyBottles / SWAPBOTTLENUM ; rest = drinked + emptyBottles % SWAPBOTTLENUM ; return drinked + solution(rest) ; } int main(int argc, char *argv[]) { vector<int> emp ; vector<int> sol ; int temp ; while(cin >> temp && temp != 0) emp.push_back(temp) ; for(auto item : emp) sol.push_back(solution(item)) ; for(auto item : sol){ cout << item << endl ; } return 0; }
方案改进
我的算法完全就是按照问题描述的思路来写的,可以用递归也可以使用迭代方法。
不过在评论区看到了更优的解法。
因为两个空瓶可以完全兑换一瓶汽水,那么我可以每次拿出两个空瓶换一瓶汽水,也没有空瓶留下,这种兑换的次数一共有n / 2次,所以一共可以得到n / 2瓶汽水。过程太简单,算法就不写了。