zoukankan      html  css  js  c++  java
  • 【面试】面试题之汽水空瓶子问题

    一、题目描述

      有这样一道智力题:“某商店规定:三个空汽水瓶可以换一瓶汽水。小张手上有十个空 汽水瓶,她最多可以换多少瓶汽水喝?”答案是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

    六、总结

      同样一个问题,换不同的思路可以有不同的解决办法,第二种思路的代码比第一种思路的代码量少很多,所以,解决一个问题时,思路往往是最重要的。谢谢各位园友观看~

  • 相关阅读:
    2017.11.20 定时器与数码管
    2017.11.19 C语言基础及流水灯实现
    libcmtd.lib(exe_wwinmain.obj) : error LNK2001: 无法解析的外部符号 _wWinMain@16
    VCatlmfcincludeafx.h(24): fatal error C1189: #error: Building MFC application with /MD[d] (CRT dll version) requires MFC shared dll version. Please #define _AFXDLL or do not use /MD[d]
    VS2015解决 error C4996: 'strdup': The POSIX name for this item is deprecated.
    vs2015单元测试
    pkg-config的一些用法
    CMake快速入门
    CMake入门教程
    Ubuntu16.04下安装NVIDIA显卡驱动
  • 原文地址:https://www.cnblogs.com/leesf456/p/5210087.html
Copyright © 2011-2022 走看看