【面試】面試題之汽水空瓶子問題

leesf發表於2016-02-23

一、題目描述

  有這樣一道智力題:“某商店規定:三個空汽水瓶可以換一瓶汽水。小張手上有十個空 汽水瓶,她最多可以換多少瓶汽水喝?”答案是5瓶,方法如下:先用9個空瓶子換3瓶汽水,喝掉3瓶滿的,喝完以後4個空瓶子,用3個再換一瓶,喝掉這瓶滿 的,這時候剩2個空瓶子。然後你讓老闆先借給你一瓶汽水,喝掉這瓶滿的,喝完以後用3個空瓶子換一瓶滿的還給老闆。如果小張手上有n個空汽水瓶,最多可以換多少瓶汽水喝?

二、輸入描述

  輸入檔案最多包含10組測試資料,每個資料佔一行,僅包含一個正整數n(1<=n<=100),表示小張手上的空汽水瓶數。n=0表示輸入結束,你的程式不應當處理這一行。

三、輸出描述

  對於每組測試資料,輸出一行,表示最多可以喝的汽水瓶數。如果一瓶也喝不到,輸出0。

四、輸入輸出示例

  輸入例子:

  3   

  10   

  81   

  0

  輸出例子:

  1   

  5   

  40

五、分析思路

  1.按照三個瓶子為主要線索進行分析。

  顯然,我們可以知道,假設有N個空瓶子,可以兌換的飲料瓶數為N/3瓶,還剩餘N - 3 * (N / 3) 個空瓶子。此時,由於兌換的汽水喝完後又會有新的空瓶子,所以進行一次兌換並且  喝完汽水後的空瓶子數量為T = N/3 + N - 3 * (N / 3),如果T = 0 或者 T = 1,則無法再兌換汽水,即問題結束;如果T = 2,則可以再兌換一瓶汽水,喝完了問題也就結束了;否則,又可以按照之前的思路進行下一步操作,即之前的N個空瓶子被替換成了N/3 + N - 3 * (N / 3),問題的規模發生了變化,思路沒有變化。很順其自然的,我們就想到了遞迴,使用遞迴來求解這個
問題。具體程式碼如下: 

import java.util.Scanner;
import java.util.List;
import java.util.ArrayList;

public class SoftDrink {
    /**
    * drunk表示此次可以喝的汽水瓶數
    * bottleNumber表示此次兌換剩餘的空瓶子數量
    */
    public static int solution(int drunk, int bottleNumber) {
        // 總共的空瓶子數量
        int total = drunk + bottleNumber;
        if (total > 2) { // 空瓶子總數大於2,問題可以繼續求解
            return drunk + solution(total / 3, total - 3 *(total / 3));
        } else if (total == 2) { // 兌換一瓶汽水,結束
            return drunk + 1;
        } else { // 無法兌換汽水,結束
            return drunk;
        }
    }
    
    public static void main(String[] args) {
        List<Integer> inputs = new ArrayList<Integer>();
        Scanner scan = new Scanner(System.in);
        while (true) {
            int input = scan.nextInt();
            if (0 == input) {
                break;
            } else {
                inputs.add(input);
            }
        }
        scan.close();
        
        for (int input : inputs) {
            int number = solution(input / 3, input - 3 *(input / 3));
            System.out.println(number);
        }
    }
}
View Code

  2.按照兩個瓶子為主要線索進行分析。

  根據題意,有兩個空瓶子,就可以找老闆再要一瓶汽水,喝完後再兌換成飲料還給老闆。所以,我們可以知道,其實只要兩個瓶子就可以換一瓶汽水(不包含瓶子,該汽水喝完後的空瓶子不能再次進行兌換,可以看成喝完後就直接丟棄),所以問題就變得十分的簡單了。具體程式碼如下:

import java.util.Scanner;
import java.util.List;
import java.util.ArrayList;

public class BottleQuestion {
    public static int solution(int n) {
        int sum = 0;
        if (n <= 1) { //一個瓶子不能換
            sum = 0;
        } else { //兩個以上可以換
            sum = n / 2; //直接除以2,因為int型別所以多一個瓶子也不影響
        }
        
        return sum;
    }
    
    public static void main(String[] args) {
        List<Integer> inputs = new ArrayList<Integer>();
        Scanner scan = new Scanner(System.in);
        while (true) {
            int input = scan.nextInt();
            if (0 == input) {
                break;
            } else {
                inputs.add(input);
            }
        }
        scan.close();
        
        for (int input : inputs) {
            int number = solution(input);
            System.out.println(number);
        }
    }
}
View Code

六、總結

  同樣一個問題,換不同的思路可以有不同的解決辦法,第二種思路的程式碼比第一種思路的程式碼量少很多,所以,解決一個問題時,思路往往是最重要的。謝謝各位園友觀看~

 

相關文章