首页 > 试题广场 >

汽水瓶

[编程题]汽水瓶
  • 热度指数:530141 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
\hspace{15pt}某商店规定:三个空汽水瓶可以换一瓶汽水,允许向老板借空汽水瓶(但是必须要归还)。
\hspace{15pt}小张手上有 n 个空汽水瓶,她想知道自己最多可以喝到多少瓶汽水。

输入描述:
\hspace{15pt}本题将会给出 1 \leqq T \leqq 10 组测试数据,确切数字未知,您需要一直读入直到特定的结尾;您也可以参考 牛客网在线判题系统使用帮助 获得更多的使用帮助。每组测试数据描述如下:

\hspace{15pt}在一行上输入一个整数 n \left(0 \leqq n \leqq 100\right) ,代表小张手上的空汽水瓶数量。特别地,n=0 代表输入结束,您只需要立即退出,不需要针对这种情况进行处理。


输出描述:
\hspace{15pt}对于每一组测试数据,新起一行。输出一个整数,代表小张最多可以喝到的汽水数量。
示例1

输入

3
10
81
0

输出

1
5
40

说明

\hspace{15pt}对于第一组测试数据,共有 3 个空瓶,可以换 1 瓶汽水。可以证明无法再做任何兑换,因此最多可以喝到 1 瓶汽水。

\hspace{15pt}对于第二组测试数据:
\hspace{23pt}\bullet\,第一轮兑换,共有 10 个空瓶。可以换 3 瓶汽水,余下 1 个空瓶;
\hspace{23pt}\bullet\,第二轮兑换,刚刚余下 1 个空瓶、加上刚刚兑换的 3 瓶汽水喝完,共有 4 个空瓶。可以换 1 瓶汽水,余下 1 个空瓶;
\hspace{23pt}\bullet\,第三轮兑换,刚刚余下 1 个空瓶、加上刚刚兑换的 1 瓶汽水喝完、再找老板借 1 个空瓶,共有 3 个空瓶。可以换 1 瓶汽水,余下 0 个空瓶。喝完之后不要忘记归还借的空瓶。
\hspace{15pt}综上,一共可以喝到 3+1+1=5 瓶汽水。
#include<stdio.h>
int main (){
    int m;
    while(~scanf("%d",&m)&&m!=0) printf("%d\n",m/2);
    return 0;
}

通过数学分析,最后获得的饮料数是总空瓶数整除2 。
编辑于 2016-03-04 16:22:57 回复(159)

python解法,思路,每两个汽水瓶换一个,所以除以2就行了。

while True:
    try:
       a=int(input())
       if a!=0:
           print(a//2)

    except:
        break
发表于 2017-10-04 20:08:50 回复(45)
//动态规划:
状态:i对应最多可换的,别忘了初始化i = 2可以换一个;
  转移方程:
i%3== 0时:   dp[i] = i/3 + dp[i/3 + i%3];
i%3!= 0时: dp[i] = i/3 + dp[i/3];


import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.TreeSet;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(new BufferedInputStream(System.in));
        PrintWriter out = new PrintWriter(new BufferedOutputStream(System.out));

        while (!sc.hasNext("0")) {
            //输入
            int n = sc.nextInt();
            if(n==1){
                System.out.println(0);
                continue;
        }
                        if(n == 2||n==3){
                System.out.println(1);
                continue;
        }
            //function函数
            int dp[]=new int[n + 1];
            dp[0] = 0;
            dp[1] = 0;
            dp[2] = 1;
            dp[3] = 1;
            dp[4] = 2;
            for (int i = 5; i < n + 1; i++) {
                if(i%3!= 0)
                    dp[i] = i/3 + dp[i/3 + i%3];
                else
                    dp[i] = i/3 + dp[i/3];
            }
            //输出
            if(n == 3){
                System.out.println(1);
                continue;
            }
            System.out.println(dp[n]);
        }
        sc.close();
        out.close();
    }
}

发表于 2021-04-06 18:27:19 回复(0)
这个案例有问题吧,最后他要求的输出结果还要加个0,害的我搞了半天,哎

发表于 2020-08-17 09:26:06 回复(1)
m = 0
while m > 10:
    try:
        count = 0
        n = int(input())
        while n > 2:
            count = n // 3
            n -= n // 3 * 2
        if n == 2:
            count += 1
        print(count)
    except:
        break

发表于 2020-03-22 21:01:17 回复(2)
#include<iostream>
#include<string>
#include<cstddef>   
#include<vector>
using namespace std;
vector<int>v;
 void track(int n)
{
v.push_back(1);
if(n<3)   
{  
 if(n==2)
    {v.push_back(1);}
return ;
}
else if(n>=3)
{
track(n-2);
}
}
int main()
{
  int n;
  while(cin>>n)
  {
  v.clear();
  int number=0;
  if(n>=3)
  {
  track(n);
  number=v.size()-1;
  }
  cout<<number<<endl;
  }
  return 0;
  }
  
发表于 2019-04-19 15:06:36 回复(0)
#include <iostream>
using namespace std;
intmain(){
    intn;
    while(cin>>n){
        cout<<n/2<<endl;
    }
}

编辑于 2017-08-08 16:32:07 回复(0)
/*
递归问题
3个瓶子换1瓶水+1个空瓶子,两个瓶子换1瓶水+0个空瓶子,1个瓶子换0瓶水。
f(1) = 0
f(2) = 1
f(3) = 1
f(4) = f(2)+1    //4个瓶子,其中3个可以换1瓶水+1个空瓶,所以是f(2)+1
f(5) = f(3)+1    //3个瓶子换1瓶水+1个空瓶,所以是f(3)+1
...
f(n) = f(n-2)+1 */
#include <iostream>
 
using namespace std;
 
int f(int n)
{
    if(n==1) return 0;
    if(n==2) return 1;
    return f(n-2)+1;
}
 
int main()
{
    int n;
    while(cin >> n){
        if(n==0)
            break;
        cout<<f(n)<<endl;
    }
    return 0;
}

发表于 2016-03-01 22:03:43 回复(25)
采用递归来看,逻辑比较清楚,n次喝到的汽水总数等于n-1次喝到汽水总数加上n-1次最终剩余的瓶子数目
import java.util.*;
public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Scanner input=new Scanner(System.in);
        while(input.hasNext()){
            int n=input.nextInt();
            int m=calSodar(n);
            System.out.println(m);
            }
        input.close();
    }
    public static int calSodar(int n){
        int a,b;        //a表示n-1次喝到的汽水总数,b表示最终剩余的瓶子数目
        if(n==2){
            a=1;b=0;
            return a+b;
        }
        else{
            if(n%2==0){
                b=1;
                a=calSodar(n-1);
                return a+b;
            }
            else{
                b=0;
                a=calSodar(n-1);
                return a+b;
            }
        }
    }

}

编辑于 2016-07-17 16:23:28 回复(0)
def bottlenumber(n):
    num = 0;
    m = 0;
    q = 0;
    if n < 2:
        return 0;
    
    else:
        while n > 1:
            m = n/3;
            num += m;
            q = n%3;
            n = m + q;
            if n == 2:
              n = 0;
              num += 1;
        return(num);
    

num2 = 0;
num2 = int(input());
bottlenumber(num2);



觉得思路没问题,但为啥答案错误:您提交的程序没有通过所有的测试用例

测试用例:
59

对应输出应该为:

29
发表于 2016-01-11 22:06:24 回复(3)
while(line = readline()){
    var num = Number(line);
    if(num!==0){
        console.log(Math.floor(num/2));
    }

}
编辑于 2020-11-12 10:39:20 回复(0)
while True:
    n = int(input())
    if n == 0: break
    print(n//2)
发表于 2021-09-06 14:31:28 回复(7)
能喝的瓶数=目前空瓶数除以2
#include <iostream>
using namespace std;
int main(int argc,char *argv[]){
    int n;
    while(cin>>n){
            cout<<n/2<<endl;
    }
    return 0;
}

编辑于 2016-06-18 22:58:34 回复(15)
// f(n)=n/3 + f(n%3+n/3),貌似递归次数更少。
// n/3是能直接换到的汽水数,n%3+n/3是新换到的汽水瓶子+上次换剩下的

import java.util.*;

public class Main {

	public static int f(int n) {
		if (n == 1)
			return 0;
		if (n == 2)
			return 1;
		return n / 3 + f(n % 3 + n / 3);
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner(System.in);
		while (sc.hasNext()) {
			int num = sc.nextInt();
			if (num != 0) {
				System.out.println(f(num));
			}
		}
		sc.close();
	}
}

编辑于 2017-07-04 17:22:14 回复(5)
//递归方法
import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        int n;
        while(sc.hasNext())
        {
            n=sc.nextInt();
            System.out.println(Drink(n));
        }
        
    }
    
    public static int Drink(int n)
    {
    	if(n<=0)
            return 0;
        else if(n==3)
            return 1;
        else if(n==2)
            return 1;
        else//此时表明对应为3的倍数,递归
        {
        	int h=0;
            h=n/3;
            return h+Drink(n-3*h+h);
        }
            
        
    }
}

发表于 2016-08-11 17:53:14 回复(11)
#include<iostream>

using namespace std;

int main(){
    int n;
    while(cin>>n){
        if(n == 0) break;
        //正常的解法
        /*int ret = 0;
        int a, b;
        while(n >= 3){
            a = n/3;
            b = n%3;
            ret += a;
            n = a + b;
        }
        if(n == 2) ret += 1;
        cout<<ret<<endl;*/
        //从给的样例中可以观察出来的规律
        cout<<n/2<<endl;
    }   
    return 0;
}

发表于 2017-06-14 17:37:47 回复(6)
import java.util.Scanner;
public class Main {
    private static int blank;
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        while (scan.hasNext()) {
            blank = scan.nextInt();
            int drink = 0;
            int remain;
            if (blank > 0 && blank <= 100) {
                if (blank == 1) {
                    drink = 0;
                } else if (blank == 2) {
                    drink = 1;
                }
                while (blank > 2) {  //10,4,5
                    drink += blank / 3;   //3 drink,4 drink
                    remain = blank % 3;  //1 remain,1 remain
                    blank = blank / 3 + remain;   //4 blank,2 blank
                    if (blank == 2) {
                        drink++;
                    }
                }
            }
            System.out.println(drink + "");
        }
    }
}
 

发表于 2016-04-05 20:24:53 回复(5)
Python: 3换1(剩2加1)程序迭代解法
import numpy
if __name__ == '__main__':
    print('Start!')
    n = int(input())
    m = 0
    if n < 2:
        print('You get no reward bottle!')
    elif n == 2:
        print('You get 1 bottle!')
    else:
        while n>2:
            m = m + n//3
            n = n//3 + n%3
        if n == 2:
            print('You get ', m + 1, ' bottle!')
        else:
            print('You get ', m, ' bottle!')


发表于 2019-09-05 17:27:57 回复(6)
# python3
import sys
def drink(n):
    if n <2:
        return 0
    elif n==2:
        return 1
    # 喝过的汽水数 -> n//3
    # 剩下的空瓶数 -> n//3 + n%3
    return n//3+drink(n//3+n%3)
for line in sys.stdin:
    n = int(line.strip())
    res =0
    res =drink(n)
    print(res)

发表于 2019-09-03 22:07:37 回复(6)
//规律是 3-1   4-2  5-2   6-3    7-3   8-4  9-4  10-5  11-5
//因此可以直接判定就是输出为输入/2
import java.util.Scanner;

public class Qi_shui_ping {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
    while(sc.hasNext())
    {
        int t=sc.nextInt();
        if(t!=0)
        System.out.println(t/2);
    }
    }
}


发表于 2019-04-23 11:13:26 回复(3)