跳到主要内容

ACM 模式

ACM 模式与核心代码模式有什么区别?​

  • 核心代码模式: 只需实现函数体, 输入输出由判题系统托管;
  • ACM 模式: 自己从标准输入读数据、自己向标准输出写结果;
  • 影响: 需要额外处理行数不定的输入与多组测试用例;
  • 语言差异: 赛码与牛客的 JS 环境提供 readline(), Node.js 环境需自行接入 readline 模块;

如何读取单行输入?​

// v8: 直接读一行
const a = readline().split(" ").map(Number);

// node: 监听 line 事件
const readline = require("readline");
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
rl.on("line", (line) => {
const tokens = line.split(" ");
console.log(parseInt(tokens[0]) + parseInt(tokens[1]));
});
  • 要点: readline() 返回字符串, 需用 split 与 map(Number) 转成数组;

如何读取固定行数的输入?​

// v8
const line1 = readline();
const line2 = readline();
print(line1.split(" "), line2.split(" "));

// node
const rows = [];
const num = 3; // 设定输入行数
rl.on("line", (data) => {
rows.push(data);
if (num === rows.length) console.log(rows); // 收满即处理
});
  • 适用: 输入行数在题面中已知且固定;

如何读取指定行数的输入?​

  • 特征: 第一行给出后续数据行数 k;
  • 思路: 用哨兵值标记"还没读到行数", 读到后按 k 收满再处理;
const readline = require("readline");
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });

let k = -1; // -1 表示尚未读到行数
const rows = [];
rl.on("line", (data) => {
if (k === -1) {
k = parseInt(data.trim()); // 第一行是行数
return;
}
rows.push(data.trim());
if (k === rows.length) console.log(rows);
});

如何读取任意行数的输入?​

  • 特征: 直到输入流结束都在持续给数据;
  • 两种写法: v8 用 while ((line = readline())) 循环; node 用 line 事件不断累积, 在 close 事件里统一处理;
const inputArr = [];
rl.on("line", (line) => inputArr.push(parseInt(line))).on("close", () => {
console.log(findMinNum(inputArr[0])); // 输入结束后再计算
});
  • 要点: close 事件是唯一能确定输入已结束的时机;