题目来源:https://www.nowcoder.com/questionTerminal/fe298c55694f4ed39e256170ff2c205f

题目:
有这样一道智力题:“某商店规定:三个空汽水瓶可以换一瓶汽水。小张手上有十个空汽水瓶,她最多可以换多少瓶汽水喝?”答案是5瓶,方法如下:先用9个空瓶子换3瓶汽水,喝掉3瓶满的,喝完以后4个空瓶子,用3个再换一瓶,喝掉这瓶满的,这时候剩2个空瓶子。然后你让老板先借给你一瓶汽水,喝掉这瓶满的,喝完以后用3个空瓶子换一瓶满的还给老板。如果小张手上有n个空汽水瓶,最多可以换多少瓶汽水喝?

输入描述:

输入文件最多包含10组测试数据,每个数据占一行,仅包含一个正整数n(1<=n<=100),表示小张手上的空汽水瓶数。n=0表示输入结束,你的程序不应当处理这一行。

输出描述:

对于每组测试数据,输出一行,表示最多可以喝的汽水瓶数。如果一瓶也喝不到,输出0。

示例:

输入
3
10
81
0

输出

1
5
40

 

本题之前没有做出来。

看到有两种解法:

解法一:

解法一的思路是通过数学分析,发现最多可以换到的汽水瓶数为输入时的瓶数除 2,例如 如果输入为 3,输出就为 1;输入为 10,输出为 5 等。

个人认为这是通过观察规律得到的,暂时没有想到或看到数学证明。

优点:代码量少;

缺点:没有严格的数学证明;

 

1 #include<iostream>
 2 using namespace std;
 3 
 4 int main()
 5 {
 6     int n;
 7 
 8     while(cin >> n)
 9     {
10         if (n <= 0 || n > 100)
11         {
12             break;
13         }
14         else 
15         {
16             cout << n / 2 << endl;
17         }
18     }
19 
20     return 0;
21 }

 


 

解法二:

解法二通过数学分析,有严谨的数学推导,发现是一个递归问题,我猜测本题的出题思路也是这样。

优点:有严谨的数学推导;直观;
缺点:代码量较解法一多;

 

/*
递归问题

3 个瓶子可以换 1 瓶水,剩下 1 个空瓶子;
2 个瓶子可以换 1 瓶水,剩下 0 个空瓶子;
1 个瓶子可以换 0 瓶水。

f(1) = 0  // 喝到 0 瓶水
f(2) = 1  // 喝到 1 瓶水,剩下 0 个空瓶子
f(3) = 1  // 喝到 1 瓶水,剩下 1 个空瓶子
f(4) = f(2)+1    // 4 个瓶子,其中 3 个可以换 1 瓶水, 剩下 2 个空瓶子,所以是 f(2) + 1
f(5) = f(3)+1    // 5 个瓶子,其中 3 个瓶子换 1 瓶水, 剩下 3 个空瓶子,所以是 f(3) + 1
...
f(n) = f(n-2)+1 */

 

1 #include <iostream>
 2   
 3 using namespace std;
 4   
 5 int f(int n)
 6 {
 7     if(n==1) return 0;
 8     if(n==2) return 1;
 9     return f(n-2)+1;
10 }
11   
12 int main()
13 {
14     int n;
15     while(cin >> n){
16         if(n == 0 || n < 0 || n > 100)
17             break;
18         cout<<f(n)<<endl;
19     }
20     return 0;
21 }

 


 

解法三:

解法三是更加自然和直接的方法,通过判断可能的条件,写出判断的函数

优点:更加直观;
缺点:代码量多;

 

1 #include <iostream>
 2 using namespace std;
 3  
 4  
 5 void helper(int &n,int &result){
 6     if(n == 1){
 7         return;
 8     }//if
 9     if(n == 2){
10         ++result;
11         return;
12     }//if
13     result += n / 3;
14     n = n % 3 + n / 3;
15     helper(n,result);
16 }
17  
18 int Drink(int n){
19     if(n <= 1){
20         return 0;
21     }//if
22     if(n == 2){
23         return 1;
24     }//if
25     int result = 0;
26     helper(n,result);
27     return result;
28 }
29  
30  
31 int main(){
32     int n;
33     
34     while(cin >> n && n > 0 && n < 100){
35         cout << Drink(n) << endl;
36     }
37     return 0;
38 }