一:问题描述

      啤酒2元一瓶,4个瓶盖换一瓶啤酒,2个空瓶换一瓶啤酒,问10元能喝几瓶啤酒?

二:问题分析

      针对上述问题,分两种情况:一种是有剩余空瓶和瓶盖且不够兑换的情况;另一种是当剩余瓶盖或空瓶不够兑换时,老板可以配合凑够;我们分别来算出喝多少瓶啤酒。【结果为:喝完第15瓶时有剩余1个空瓶3个盖不够兑换;如果老板配合,喝20瓶啤酒正好无剩余瓶盖和空瓶】

三:程序实现

     先实现一个啤酒类:

package com.challenge.beer;
public class Beer {
 /**
  * 2元1瓶啤酒
  * 4个盖子换1瓶酒
  * 2个空瓶换1瓶酒
  * 10元可以喝几瓶酒
  */
 public int Money;
 public int Gai;
 public int Empty;
 public int beer;
 
 public int borrowGai;
 public int borrowEmpty;
 int Count1=0,Count2=0; 
 
 public Beer(int money, int gai, int empty, int beer) {
  super();
  Money = money;
  Gai = gai;
  Empty = empty;
  this.beer = beer;
 }
 public Beer(int borrowGai, int borrowEmpty) {
  super();
  this.borrowGai = borrowGai;
  this.borrowEmpty = borrowEmpty;
 }
 
 public void Drink(int money,int gai,int empty){//喝酒函数
  if(money>0){
   beer=money/2;
   Gai=money/2;
   Empty=money/2;
  }else{
   Gai=gai;
   Empty=empty;
  }  
  
  System.out.println("开始喝酒:瓶盖="+Gai+";空瓶="+Empty+";啤酒="+beer+"瓶"+"\n");
  
  do{
   if(Gai>=4){
    int tmp1=Gai%4;
    int tmp2=(int)Gai/4;
    beer+=tmp2;
    Gai=tmp1+tmp2;
    Empty+=tmp2;
    Count1++;
    System.out.println("第"+Count1+"次瓶盖换酒:瓶盖="+Gai+";空瓶="+Empty+";啤酒="+beer+"瓶"+"\n"); 
   }
   
   if(Empty>=2){
    int tmp3=(int)Empty/2;//换酒   
    int tmp4=Empty%2;//剩余空瓶
    Gai+=tmp3;//新盖
    Empty=tmp4+tmp3;
       beer+=tmp3;
       Count2++;
    System.out.println("第"+Count2+"次空瓶换酒:瓶盖="+Gai+";空瓶="+Empty+";啤酒="+beer+"瓶"+"\n");
   }
   System.out.println("喝了:"+beer+"瓶啤酒"+"\n"); 
   
   //判断是否要还空瓶或者瓶盖
   if(borrowGai >0||borrowEmpty>0){
    Return(); 
   }
    
  }while(Gai>=4 || Empty>=2);  
  
  //借瓶盖或者空瓶函数
  Borrow();
 }
 
 public void Borrow(){//借瓶盖或者空瓶函数  
  if(Gai==0 && Empty==0){
   System.out.println("-----OVER!喝酒结束---");
  }else{
   
   if(4-Gai>2-Empty ){ //判断借空瓶还是借盖,借最少优先
    int tmp=2-Empty;
    Empty+=tmp;  //借空瓶
    this.borrowEmpty+=tmp;
    System.out.println("借了:"+this.borrowGai+"个盖;"+tmp+"个空瓶"+"\n"); 
    Drink(0,Gai,Empty);
    
   }else{
    int tmp=4-Gai;
    Gai+=tmp;//借盖
    this.borrowGai+=tmp;
    System.out.println("借了:"+tmp+"个盖;"+"\n"); 
    Drink(0,Gai,Empty);
   }
  }
 }
 
 public void Return(){//归还空瓶/瓶盖函数
  //归还瓶盖
  if(borrowGai>0){
   if(Gai>0&&Gai>=borrowGai){
    Gai-=borrowGai;
    System.out.println("归还:"+this.borrowGai+"个盖;"+"\n"); 
    borrowGai=0;
   }
  }
  //归还空瓶
  if(borrowEmpty>0){
   if(Empty>=borrowEmpty){
    Empty-=borrowEmpty;
    System.out.println("归还:"+this.borrowEmpty+"个空瓶"+"\n"); 
    borrowEmpty=0;
   }
  }  
 }
}

       再通过主类调用该类对象:

 package com.challenge.beer;
public class Main {
 /**
  * @param args
  */
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  Beer p=new Beer(10,0,0,0);
  p.Drink(10,0,0);
 }
}

三:程序输出结果

开始喝酒:瓶盖=5;空瓶=5;啤酒=5瓶

第1次瓶盖换酒:瓶盖=2;空瓶=6;啤酒=6瓶

第1次空瓶换酒:瓶盖=5;空瓶=3;啤酒=9瓶

喝了:9瓶啤酒

第2次瓶盖换酒:瓶盖=2;空瓶=4;啤酒=10瓶

第2次空瓶换酒:瓶盖=4;空瓶=2;啤酒=12瓶

喝了:12瓶啤酒

第3次瓶盖换酒:瓶盖=1;空瓶=3;啤酒=13瓶

第3次空瓶换酒:瓶盖=2;空瓶=2;啤酒=14瓶

喝了:14瓶啤酒

第4次空瓶换酒:瓶盖=3;空瓶=1;啤酒=15瓶

喝了:15瓶啤酒

借了:1个盖;

开始喝酒:瓶盖=4;空瓶=1;啤酒=15瓶

第4次瓶盖换酒:瓶盖=1;空瓶=2;啤酒=16瓶

第5次空瓶换酒:瓶盖=2;空瓶=1;啤酒=17瓶

喝了:17瓶啤酒

归还:1个盖;

借了:0个盖;1个空瓶

开始喝酒:瓶盖=1;空瓶=2;啤酒=17瓶

第6次空瓶换酒:瓶盖=2;空瓶=1;啤酒=18瓶

喝了:18瓶啤酒

归还:1个空瓶

借了:2个盖;

开始喝酒:瓶盖=4;空瓶=0;啤酒=18瓶

第5次瓶盖换酒:瓶盖=1;空瓶=1;啤酒=19瓶

喝了:19瓶啤酒

借了:2个盖;1个空瓶

开始喝酒:瓶盖=1;空瓶=2;啤酒=19瓶

第7次空瓶换酒:瓶盖=2;空瓶=1;啤酒=20瓶

喝了:20瓶啤酒

归还:2个盖;

归还:1个空瓶

-----OVER!喝酒结束---