ACM模式输入输出
🧰 JavaScript(Node.js)中如何读取输入?
在浏览器中我们用 prompt()
,但在 Node.js 环境(ACM 模式常用)中,我们需要使用 readline
模块来处理输入。
✅ 基础模板:Node.js 读取多行输入
const readline = require('readline');// 创建 readline 接口
const rl = readline.createInterface({input: process.stdin,output: process.stdout
});// 用于存储输入的数据
let input = [];// 每当输入一行时,触发 'line' 事件
rl.on('line', (line) => {input.push(line.trim());// 在这里可以处理逻辑,或者等所有输入结束后统一处理
});// 输入结束时(如 Ctrl+D),触发 'close' 事件
rl.on('close', () => {// 所有输入已经读取完毕,开始处理solve(input);process.exit(0); // 退出程序
});// 解决问题的函数
function solve(input) {// 在这里写你的逻辑// input 是一个字符串数组,每一项是一行输入console.log('输入的内容:', input);// 示例:假设输入两行,第一行是数字 n,第二行是 n 个数const n = parseInt(input[0]);const arr = input[1].split(' ').map(Number);console.log('n:', n);console.log('数组:', arr);// 输出结果(必须用 console.log)console.log(arr.reduce((a, b) => a + b));
}
📚 输入格式常见类型
1. 单行输入:1 2 3 4 5
const arr = input[0].split(' ').map(Number);
2. 多行输入:
3
1 2 3
4 5 6
7 8 9
const n = parseInt(input[0]);
for (let i = 1; i <= n; i++) {const row = input[i].split(' ').map(Number);
}
3. 不确定行数(以空行为结束)
需要在 close 事件中处理
✅ 输出:使用 console.log()
在 ACM 模式中,输出必须使用:
console.log(result);
⚠️ 注意:
- 不要使用
return
- 不要使用
alert
、prompt
- 输出格式要严格匹配题目要求(比如换行、空格)
🧪 实战例子:两数之和(ACM 模式)
📥 输入格式:
2
1 2
3 4
📤 输出格式:
3
7
✅ 代码:
const readline = require('readline');const rl = readline.createInterface({input: process.stdin,output: process.stdout
});const input = [];rl.on('line', (line) => {input.push(line.trim());
});rl.on('close', () => {// 第一行是 n,表示有 n 行const n = parseInt(input[0]);for (let i = 1; i <= n; i++) {const [a, b] = input[i].split(' ').map(Number);console.log(a + b);}process.exit(0);
});
🎯 常见输入场景模板
模板 1:读取一行两个数
const [a, b] = input[0].split(' ').map(Number);
模板 2:读取 n 行数据
const n = parseInt(input[0]);
for (let i = 1; i <= n; i++) {const data = input[i].split(' ').map(Number);
}
模板 3:矩阵输入
const [n, m] = input[0].split(' ').map(Number);
const matrix = [];
for (let i = 1; i <= n; i++) {matrix.push(input[i].split(' ').map(Number));
}
⚠️ 注意事项
问题 | 解决方案 |
---|---|
输入没读完 | 确保 rl.on('close') 中处理所有逻辑 |
类型错误 | 用 parseInt() 、parseFloat() 或 .map(Number) 转换 |
多余空格 | 使用 .trim() |
输出格式错误 | 严格按照题目要求输出(不要多空格、换行) |
本地测试 | 可以用 `echo “1 2” |
💡 本地测试技巧
你可以这样测试你的代码:
# 方法1:手动输入
node solution.js
# 然后输入数据,按 Ctrl+D 结束输入# 方法2:用 echo
echo -e "2\n1 2\n3 4" | node solution.js# 方法3:用文件
node solution.js < input.txt
✅ 总结:ACM 模式 JS 模板(推荐收藏)
const readline = require('readline');const rl = readline.createInterface({input: process.stdin,output: process.stdout
});const input = [];rl.on('line', (line) => {input.push(line.trim());
});rl.on('close', () => {solve(input);process.exit(0);
});function solve(input) {// 在这里写你的算法逻辑// 使用 console.log 输出结果
}
非常好的问题!👏
你问到了 ACM 模式中非常关键的一点:如何处理“不确定类型”的输入,比如:
- 有些题目输入是字符串(如
"abc"
、"hello world"
) - 有些是混合类型(如
"Alice 25"
) - 有些是带空格的句子
我们来一一解答。
✅ 核心原则
不要提前转换类型!先按字符串读取,再根据题目要求处理。
🎯 场景 1:输入是纯字符串(如姓名、单词)
📥 输入:
Alice
Bob
Charlie
✅ 处理方式:
直接使用字符串,不要用 Number
或 parseInt
const names = [];
for (let i = 0; i < 3; i++) {names.push(input[i]); // 直接用字符串
}
console.log(names); // ['Alice', 'Bob', 'Charlie']
🎯 场景 2:一行中有字符串和数字(混合类型)
📥 输入:
Alice 25
Bob 30
Charlie 35
✅ 处理方式:
先 split(' ')
,然后分别处理每个字段
const people = [];
for (let i = 0; i < 3; i++) {const parts = input[i].split(' ');const name = parts[0]; // 字符串const age = parseInt(parts[1]); // 数字people.push({ name, age });
}console.log(people);
// [{name: 'Alice', age: 25}, ...]
🎯 场景 3:字符串中包含空格(如一句话)
📥 输入:
Hello world
I love coding
JavaScript is awesome
❌ 错误做法:
input[0].split(' ') // → ['Hello', 'world'],被拆开了
✅ 正确做法:
不要拆!直接使用原字符串
const sentences = [];
for (let i = 0; i < 3; i++) {sentences.push(input[i]); // 完整保留空格
}console.log(sentences);
// ['Hello world', 'I love coding', 'JavaScript is awesome']
🎯 场景 4:一行输入,前几个是字符串,后几个是数字
📥 输入:
3
apple 10 2.5
banana 5 3.0
cherry 8 2.0
表示:水果名、数量、单价
✅ 处理:
const n = parseInt(input[0]);
const fruits = [];for (let i = 1; i <= n; i++) {const parts = input[i].split(' ');const name = parts[0];const count = parseInt(parts[1]);const price = Number(parts[2]);fruits.push({ name, count, price });
}
🎯 场景 5:输入是 JSON 字符串(少见但可能)
📥 输入:
{"name": "Alice", "age": 25}
{"name": "Bob", "age": 30}
✅ 处理:
用 JSON.parse
const people = input.map(line => JSON.parse(line));
✅ 总结:如何判断用什么方式处理?
输入内容 | 处理方式 |
---|---|
纯数字(1 2 3 ) | .split(' ').map(Number) |
纯整数个数(3 ) | parseInt(input[0]) |
纯字符串(Alice ) | 直接用 input[i] |
混合类型(Alice 25 ) | split(' ') 后分别处理 |
带空格的句子(Hello world ) | 不要 split ,直接用原字符串 |
不确定类型 | 先当字符串处理,后续再判断 |
✅ 通用建议(ACM 模式)
rl.on('line', line => {input.push(line.trim());
});rl.on('close', () => {// 第一步:先打印看看输入长什么样(调试用)console.error('输入:', input); // 注意:用 console.error 不影响输出// 第二步:根据题目描述,决定如何解析// 比如题目说“第一行是n,接下来n行每行是 a b c”const n = parseInt(input[0]);for (let i = 1; i <= n; i++) {const parts = input[i].split(' ');// 再根据字段含义转换类型}
});
💡 一句话记住:
在 ACM 模式中:
- 数字才转,字符串不转
- 先看题目描述,再决定怎么拆和转
- 不要盲目
.map(Number)
🎉 搞定!你现在不仅能处理数字,还能灵活应对各种字符串输入了!
需要我帮你练习一个“混合类型”的 ACM 题目吗?比如“学生成绩排序”(姓名+分数)?