编程题 - 汽水瓶【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();
相关推荐
牧杉-惊蛰5 小时前
css 数字从0开始增加的动画效果
前端·javascript·css
孤灯淡茶5 小时前
Fiori学习专题十五:Nested Views
前端·javascript·学习
Monly215 小时前
Vue:el-table-tree懒加载数据
前端·javascript·vue.js
进取星辰5 小时前
16、路由守卫:设置魔法结界——React 19 React Router
前端·javascript·react.js
半块橘子6 小时前
Electron-vite中ELECTRON_RENDERER_URL环境变量如何被设置的
前端·javascript·electron
whistle哨子6 小时前
electron-vite 应用打包自定义图标不显示问题
javascript·electron
Jiaberrr7 小时前
uniapp 实现低功耗蓝牙连接并读写数据实战指南
java·前端·javascript·vue.js·struts·uni-app
林小白的日常7 小时前
uniapp打包apk如何实现版本更新
前端·javascript·uni-app
2c237c68 小时前
使用Node编写轻量级后端快速入门
后端·arcgis·node.js·c5全栈
AscendKing8 小时前
donet使用指定版本sdk
javascript·windows