编程题 - 汽水瓶【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();
相关推荐
老毛肚8 小时前
jeecg-boot-base-core 02 day
javascript·python
烬羽13 小时前
后端返回的 JSON 字符串,浏览器怎么"看懂"的?——Ajax 全链路拆解
javascript
zhuxiaojt13 小时前
npx 为何如此之慢?浅谈 npx 速度慢的原因及工具推荐
node.js
半个落月14 小时前
一个新手用 Bun + Axios 调通 DeepSeek API 的实践记录
javascript
不好听61314 小时前
深入理解链表:线性数据结构的另一面
javascript·数据结构
林希_Rachel_傻希希14 小时前
学React治好了我的焦虑症,1小时速通React 前20分钟。
前端·javascript·面试
小林ixn14 小时前
从 Ajax 到异步编程:JSON 序列化、Event Loop 与 XHR 请求完全解析
javascript
码农刚子14 小时前
从零开始:在 Windows 服务器上部署 Node.js 项目(小白实战教程)
后端·node.js
丷丩15 小时前
MapLibre GL JS第47课:添加动画图标
javascript·gis·动画·mapbox·maplibre
快乐的哈士奇15 小时前
【Next.js实战①】Gmail API 按柜号检索邮件:OAuth 双 Cookie 与搜索 Fallback
开发语言·javascript·ecmascript