编程题 - 汽水瓶【JavaScript/Node.js解法】

‌"学如逆水行舟,不进则退。"‌ ------《增广贤文》

目录

汽水瓶 题目:

某商店规定:三个空汽水瓶可以换一瓶汽水,允许向老板借空汽水瓶(但是必须要归还)。

小张手上有 n 个空汽水瓶,她想知道自己最多可以喝到多少瓶汽水。
输入描述:

本题将会给出 1<=T <=10 组测试数据,确切数字未知,您需要一直读入直到特定的结尾。每组测试数据描述如下:在一行上输入一个整数 n (0 <= n <=100) ,代表小张手上的空汽水瓶数量。特别地,n=0 代表输入结束,您只需要立即退出,不需要针对这种情况进行处理。
输出描述:

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

输入例子:

3

10

81

0

输出例子:

1

5

40
例子说明:

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

对于第二组测试数据:

  • 第一轮兑换,共有 10 个空瓶。可以换 3 瓶汽水,余下 1 个空瓶;
  • 第二轮兑换,刚刚余下 1 个空瓶、加上刚刚兑换的 3 瓶汽水喝完,共有 4 个空瓶。可以换 1 瓶汽水,余下 1 个空瓶;
  • 第三轮兑换,刚刚余下 1 个空瓶、加上刚刚兑换的 1 瓶汽水喝完、再找老板借 1 个空瓶,共有 3 个空瓶。可以换 1 瓶汽水,余下 0 个空瓶。喝完之后不要忘记归还借的空瓶。
  • 综上,一共可以喝到 3+1+1=5 瓶汽水。

解答分析:

可以用来换的瓶子是 总瓶子 / 3 的值,那么现在手里的瓶子就是 没换的瓶子(余数)+ 换来的瓶子。我们进行循环处理直到最后剩下两个瓶子的时候可以借老板一个瓶子,三个瓶子换一瓶汽水,喝完还给老板。而剩下的瓶子小于两瓶的话不做处理。

js代码解答 -ACM模式:

不懂nodejs的readline请点击跳转 -- readline模块详解【Node.js】 作者:幸运小圣

javascript 复制代码
 const readline = require('readline');
 const rl = readline.createInterface({
    input:process.stdin,
    output:process.stdout,
 });

function calculateBottles(val) {
    let totalBottles = 0;
    while (val >= 3) {
        let newBottles = Math.floor(val / 3);
        totalBottles += newBottles;
        val = val % 3 + newBottles;
    }
    if(val == 2){
        totalBottles += 1;
    }
    return totalBottles;
}
async function processInput(){
    for await (const line of rl){
        let val = Number(line);
        if(val == 0){
            break;
        }
        if(val > 2){
           console.log(calculateBottles(val));
        }
        rl.close();
    }
}
processInput();

代码通过:

题解分析:

每次兑换后,都会产生新的空瓶(即喝掉的汽水瓶)。

这些新的空瓶又可以继续兑换,直到空瓶数不足以再兑换为止。

通过观察或数学归纳,我们可以发现一个规律:在允许借瓶的条件下,最多可以喝到的汽水数量大致等于初始空瓶数的一半(当n较大时,这个近似更加准确)。

‌为什么等于总瓶子除以2‌:

  • 这是因为每次兑换都会"消耗"3个空瓶,但"产生"1瓶汽水(即1个新的空瓶)。
  • 从长期来看,每2个空瓶(加上借的1个空瓶)可以"变成"1瓶汽水。
  • 因此,在大量兑换的情况下,最多可以喝到的汽水数量趋近于初始空瓶数的一半。

简洁思路代码:

javascript 复制代码
const readline = require('readline');
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });

async function processInput () {
  for await (const line of rl) {
    let val = Number(line);
    if (val === 0) {
      break;
    }
    let maxBottles = Math.floor(val / 2);
    console.log(maxBottles);
    rl.close();
  }
}

processInput();
相关推荐
前端精髓9 小时前
移除 Effect 依赖
前端·javascript·react.js
码云之上9 小时前
从一个截图函数到一个 npm 包——pdf-snapshot 的诞生记
前端·node.js·github
lpfasd12310 小时前
TypeScript + Cloudflare 全家桶部署项目全流程
前端·javascript·typescript
前端Hardy10 小时前
字节/腾讯内部流出!Claude Code 2026王炸玩法!效率暴涨10倍
前端·javascript·vue.js
前端Hardy11 小时前
大厂都在偷偷用的 Cursor Rules 封装!告别重复 Prompt,AI 编程效率翻倍
前端·javascript·面试
kyriewen11 小时前
Vite:比Webpack快100倍的“闪电侠”,原理竟然这么简单?
前端·javascript·vite
竹林81811 小时前
RainbowKit快速集成多链钱包连接:从“连不上”到丝滑切换的踩坑实录
前端·javascript
Kel11 小时前
Pi Monorepo Stream Event Flow 深度分析
人工智能·架构·node.js
前端Hardy11 小时前
Cursor Rules 完全指南(2026 最新版)
前端·javascript·面试
牛奶11 小时前
浏览器是怎么把代码变成页面的?
前端·javascript·chrome