// 21名运动员想要买可乐喝,现得知商家正在举行一项促销活动:
// 凡3个空可乐瓶都可以免费换取一瓶可乐;请问至少需要买多少瓶可乐才能以
// 最少代价让每个人都喝到可乐?
public static void main(String[] args)
{
final int NUM = 21;
int number =0;
int kongping =0;
for (int i = 0; i < 21; i++,number++,kongping++)
{

if (kongping == 3)
{
number = number+1;
kongping = 1;
}
if(number == NUM)
{
System.out.println(i);
break;
}
} }

解决方案 »

  1.   

    个人拙见
    public static void main(String[] args)
        {
            final int NUM = 21;
            int number =0;
            for(int i =0;i<NUM;i++){ 
             if((number+number/3)>=21){
             System.out.println(number);
             break;
             }
             number++;
            }
     
        }
      

  2.   

    把循环内部的条件判断向前挪一下,或者number == NUM改成number >= NUM。不然你的number会在空瓶那里再加上1
    public static void main(String[] args)
        {
            final int NUM = 21;
            int number =0;
            int kongping =0;
            for (int i = 0; i < 21; i++,number++,kongping++)
            {
                 if(number == NUM)
                {
                    System.out.println(i);
                    break;
                }
                if (kongping == 3)
                {
                    number = number+1;
                    kongping = 1;
                }
                
            }
     
        }
      

  3.   

    [size=16px]下面[size=13px]让我来解释一下为什么说买15瓶是正确答案:@表示买的那瓶水,而1表示送的那瓶水,下面用图解法分析一下:
    @@@   1@@   1@@   1@@    1@@    1@@    1@@   
    第一个@@@表示先买了三瓶水,下面的1@@表示送了一瓶水加上之后再买的两瓶水凑成三瓶水,然后又可以送一瓶水。[/size]这样买的水的瓶数(即@的个数)共有15瓶。[/size]
      

  4.   

    public static void main(String arg[]){
    int cocaNum=0;   //可乐总数
    int buyCocaNum=0;  //购买数
    int emptyCocaNum=0;  //空瓶数

    while(21>=cocaNum){  
    buyCocaNum++; 
    cocaNum++;
    emptyCocaNum++;
    if(0==emptyCocaNum%3){
    cocaNum++;
    emptyCocaNum++;
    }

    }
    System.out.println("需要购买可乐的数量为:"+buyCocaNum);
    }
      

  5.   

    public static void main(String[] args)
        {
            final int NUM = 21;
            int number =0;
            int kongping =0;
            for (int i = 0; i < 21; i++,number++,kongping++)
            {
                 if(number == NUM)
                {
                    System.out.println(i);
                    break;
                }
                if (kongping == 3)
                {
                    number = number+1;
                    kongping = 1;
                }
                 
            }
      
        }
      

  6.   

    package chopper.java.test;public class coca {
    static int playerNum =21;
    static int cheapAlg(int number){
    int buyNum =0;
    for (int i =0;i<= 21;i++){
    if(i%4 ==0)
    continue;
    buyNum ++;
    }
    return buyNum;
    }
    public  static void main(String[] args){
    int buyNum =0;
    buyNum = cheapAlg(playerNum);
    System.out.println("We need buy "+ buyNum + " at least");
    }}
      

  7.   

    我这个方法比较简单也比较繁琐还比较特殊,因为我没有用循环就得出了答案,当然效率要比这种i++的要高很多,但是,时间复杂度自然也下去了。我现在把答案贴出来,自带注释。import java.util.Scanner;// 21名运动员想要买可乐喝,现得知商家正在举行一项促销活动:
    // 凡3个空可乐瓶都可以免费换取一瓶可乐;请问至少需要买多少瓶可乐才能以
    // 最少代价让每个人都喝到可乐?
    public class suanfa { /**
     * @param args
     */
    public static void main(String[] args) {
    // TODO Auto-generated method stub
    /**
     * 请注意空瓶是也可以换可乐的
     * 思路:分组方法(3个一组)第一组买三个coco 得到一个exchange;将exchange放入第二组买再买2个coco 即可得到第二个exchange 以此类推
     * 得到公式   
     * 总数 = 3 + (总数-3)/3*2 + (总数-3)/3 + 1+N    0<=N<=2
     * 从上面的式子不难看出 
     * 在总数可以被整除的情况下:
     * paycoco = 3+ (总数-3)/3*2 
     * 在被除后有余数的情况下:
     * paycoco = 3+ (总数-3)/3*2 + 总数%3 - 1
     */
    Scanner input = new Scanner (System.in);
    int total = input.nextInt();
    int paycoco;
    if (total%3==0) {
    paycoco = 3+(total-3)/3*2;
    }else {
    paycoco = 3+(total-3)/3*2+total%3-1;
    }
    System.out.println("只要买   "+paycoco+" 瓶,即可让每个人都喝到可乐");

    }}
    运行后楼主会发现 22人也是 只要买15瓶即可,因为21可以被三整除,商家又赠了一瓶,23人是要买16瓶。
    在编程过程中遇到类似问题要尽量避免这种i++的循环出现,以减少时间复杂度,为程序提高运行效率。
    假如这个数有N位,那么i要循环多少次可想而知,性能上也就不用提了,但是公式法只要输数就出值,要快很多。
      

  8.   

    public class SumBottle {
    public static void main(String[] args) {
    int bottle = 21;
    int sum = 0;
    int flag = 0;
    while(bottle>2) {
    flag = bottle;
    while(flag > 0) {
    sum += flag;
    flag = flag / 3;
    }
    if(21 == sum) {
    System.out.println(bottle);
    break ;
    }
    bottle -- ;
    sum = 0;
    }
    }
    有什么要改进的请指点。
      

  9.   

    理解为线程题:
    static final long Q = 10000l; //喝一瓶的时间
    static final long H = 5000l; //买一瓶 和换一瓶的时间
    static final int MUN = 21 ; //总的人数
    static int k = 0 ;//空瓶数
    static int m = 0 ;//买的数量
    static int h = 0 ;//换的数量
    static  boolean isH = false ;//控制是否换瓶
    public static void main(String[] args)



    while (true) {
    try {
    Thread.sleep(H) ;
    m++ ;
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    if(k != 0 && k%3 == 0)
    try {
    Thread.sleep(H) ;
    h++ ;
    isH = true ;
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    if(m+h == MUN){
    System.out.println("一共买了"+m + "瓶");
    return ;
    }
    new Thread( new Runnable() {
    @Override
    public void run() {
    try {
    Thread.sleep(Q) ;
    k++ ;
    if(isH)
    k++ ;
    isH = false ;
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    }
    ).start() ;

    }



    // new Main().init() ;
    }
      

  10.   


    实际上正确答案就是15,因为你就买了15瓶;但是如果可退货的话,只是花了14瓶的钱。
    答:买15瓶,但是最后退了一瓶所以只花了14瓶的钱。
    补充一下昨天的答案:import java.util.Scanner;// 21名运动员想要买可乐喝,现得知商家正在举行一项促销活动:
    // 凡3个空可乐瓶都可以免费换取一瓶可乐;请问至少需要买多少瓶可乐才能以
    // 最少代价让每个人都喝到可乐?
    public class suanfa { /**
     * @param args
     */
    public static void main(String[] args) {
    // TODO Auto-generated method stub
    /**
     * 请注意送的可乐喝完是也可以换的
     * 思路:分组方法  第一组买三个coco 得到一个exchange;将exchange放入第二组买再买2个coco 即可得到第二个exchange;以此类推
     * 得到公式   :
     * 总数 = 3 + (总数-3)/3*2 + (总数-3)/3 + 1+N    0<=N<=2
     * 从上面的式子不难看出 
     * 在 总数可以被整除的情况下:
     * paycoco = 3+ (总数-3)/3*2 
     * 在被除后有余数的情况下:
     * paycoco = 3+ (总数-3)/3*2 + 总数%3 - 1
     */
    Scanner input = new Scanner (System.in);
    int total = input.nextInt();
    int paycoco;
    if (total%3==0) {
    paycoco = 3+(total-3)/3*2;
    System.out.println("只要买   "+paycoco+
    " 瓶,即可让每个人都喝到可乐;但是如果可以退货,那么最后三个空瓶可以换一瓶coco,冰枪老板退货,这样实际上只需要支付 "
    +(paycoco-1)+"瓶的金额即可满足所有人需求。");
    }else {
    paycoco = 3+(total-3)/3*2+total%3-1;
    }
    System.out.println("只要买   "+paycoco+" 瓶,即可让每个人都喝到可乐");

    }}
      

  11.   

    package test0311;public class Test2 { /**
     * @param args
     */
    public static void main(String[] args) {
    int Num = 21;
    int countPay = 0;
    int kongping = 0;
    for (int i = 0; i < 21; i++) { if (Num > 0) {
    countPay++;
    Num--;
    kongping++;
    if (kongping == 3) {
    kongping = 1;
    Num--;
    } } else {
    System.out.println("pay+" + countPay);
    break;
    } }
    }}
      

  12.   

    怎么感觉4x+x/3>=21应买的瓶数为 x*3呢!?
      

  13.   

    设运动员总数为s,至少需要购买的可乐瓶数为x,那么有
    x + x/3 + x/3^2 + ... + x/3^n >= s
    左边是等差数列,求和转换后为
    x >= (2s/3) / (1 - 1/3^n)
    可知当n为无穷大时,x取得最小值2s/3代码如下:public class Test1 {
    public static void main(String[] args) {
    System.out.println(getNum(5));
    System.out.println(getNum(6));
    System.out.println(getNum(7));
    System.out.println(getNum(21));
    }

    static int getNum(int s) {
    return (int)Math.ceil(2.0 / 3 * s);
    }
    }
      

  14.   

    21名运动员想要买可乐喝,现得知商家正在举行一项促销活动:
    凡3个空可乐瓶都可以免费换取一瓶可乐;请问至少需要买多少瓶可乐才能以
    最少代价让每个人都喝到可乐?

    你们全错了,这里说的是最少代价,而不是最少money。应该是21瓶。
    请你们自己思考,就不说你们是运动员了。
    就说你们是公司主持去旅游,到了某个景区,狂玩一阵子后,大家非常渴,
    然后公司让人给你们买水喝,如果是买三瓶换一瓶的喝,你会怎么想?
    小气、抠门对不对。
    不是每个人都一口干,有的人一瓶水要喝很久。
    尤其是最后一个还有水喝的那位,
    我估计很大可能,宁可渴着,也不要这瓶水。
    以后的结果,不用想也知道。
    如果一次每人一瓶那就不一样了。至少你们会觉得这是很平常的事,不会应水的原因觉得公司小气。
      

  15.   

    改成21个程序员好了...
    再贴下传统解法,结果应该是14: static int getNum2(int s) {
    int sum = 0;
    int empty = 0;
    for (int i = 1; i <= s; ++i) {
    if (empty == 3) {
    empty = 1;
    } else {
    ++sum;
    ++empty;
    }
    }
    if(empty == 3) --sum;
    return sum;
    }
      

  16.   

    public static void main(String[] args) {
    final int NUM = 21;
    int number = 0;
    int kongping = 0;
    for (int i = 0; i < 21; i++, number++, kongping++) { if (number == NUM) {
    System.out.println(i); break;
    } else if (kongping == 3) { number = number + 1;
    kongping = 1; } } }
      

  17.   

    public class ExchangeBottle {
    public static int total; //total表示i个可乐总共能换多少瓶
    public static int empty;//空瓶数
    public static int mod;//剩下的空瓶数
    public static int div;//换到的可乐
    public static void main(String[] args) {
    int t;
    for(int i=0;i<21;i++){
    total=i;
    empty=i;
    t=gettotal(i);
    if(t>=21){
    System.out.println(i);
    break;
    }
    }
    }
    public static int gettotal(int i){
    div=empty/3;
    mod=empty%3;
    total+=div;
    empty=div+mod;
    if(div+mod>=3){
    gettotal(div);}  
    return total;
    }
    }
    刚学java不久,写的有点复杂了,不过还是能算出来