Java 在 ACM 模式下的输入输出
相信我们已经非常熟悉 LeetCode 那种「站内文章核心代码」的写题模式,在这种模式下,我们可以更专注于代码逻辑本身。然而一些公司或学校的机考仍然使用 ACM 标准文件输入输出模式,在这种模式下需要对题目输入输出的逻辑进行额外的处理。
不同公司/机构的笔试模式
仅记录个人经验
| 年份 | 公司 | 环节 | 代码模式 | 代码联想 | 正确性检验 | 其它补充 | 是否允许本地 IDE |
|---|---|---|---|---|---|---|---|
| 2024 | 字节 | 手撕 | ACM 模式 | ✅ | 自行检验 | 类似「掘金」的刷题平台,有代码联想和预先示例,有编辑器错误提示。 | 询问面试官 |
| 2025 | 美团 | (忘了) | 面试端的编码页面。有 main 函数和核心函数框架。 | ||||
| 拼多多、高德地图 | 记事本模式 | ✅ | 自行检验/面试官检验 | 纯记事本,代码由面试官运行或目视检查。 | |||
| 2023 | USTC | 机试 | 核心代码模式 | (忘了) | 自行检验 | 记得时刻在剪切板保存好自己的代码,不要误触按钮导致一键清空。 | ❌线下专机考试,可携带书籍 |
| 2025 | 华为 | ACM 模式 | ❌ | 自行检验/用例通过状态 | Java 只给 main 函数,部分包要自己引用。Scanner 自己写但有提示。类似 iLearning 平台。9 月中旬机试系统改版,需安装时习之 APP。APP 对电脑系统软件会进行严格管控。 | ✅ | |
| 小米集团 | ✅ | 使用赛马在线考试客户端。代码页为空,但有输入输出提示。 | |||||
| 小红书、京东、科大讯飞 | 使用赛马在线考试网页版。 | ||||||
| 网易互娱、美团、新华三 | 牛客机试系统。非双机位。 | ||||||
| 美团、拼多多、蚂蚁集团 | 牛客机试系统。使用双机位。 |
牛客网部分笔试中,会出现 ACM 模式与核心代码模式混用的情况。
Main 类的写法
像牛客、华为等机构机试都会给出最基础的代码模板。一些 OJ 中的代码编辑器不会给出任何内容(洛谷、Codeforces),这就需要我们手写 Main 类。注意,这个 Main 类是有固定格式的,不能随便改动,否则将报运行时错误。
1 | import java.util.Scanner; |
小提示:对于第一次进陌生的 OJ,可以先写题库的第一道题「A+B」熟悉机试形式。一般题面或题解中附有不同语言的正确的写法。
输入与输出
输出写法 sout
最最基本的输出写法。
1 | System.out.println("Hello Nowcoder!"); // 换行输出 IDEA 下快捷输入:sout |
输入写法 java.util.Scanner
java.util.Scanner 是 Java 5 的新特征,我们可以通过 Scanner 类来获取用户的输入。这种输出写法比较简单,但在极端场景下容易超时。
1 | import java.util.Scanner; |
华为机试中,需要手写包的导入以及
Scanner的创建。
输入时用到类 Scanner 类,里面有几个常用方法:
hasNext():用于判断是否还有输入的数据,常放在 while 循环中判断输入是否结束。next():读到空格就停止读取。适合读取单个字符或字符串。返回类型String。nextLine():读取一整行数据,碰到换行则停止。返回类型String
next() 与 nextLine() 区别:
| 函数 | next() | nextLine() |
|---|---|---|
| 是否阻塞 | 一定要读取到有效字符后才可以结束输入 | |
| 结束符 | 对输入有效字符之前遇到的空白,next() 方法会自动将其去掉。只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符。 | 以 Enter 为结束符,该返回的是输入回车之前的所有字符。 |
| 带空格字符串 | 🟥 | 🟩 |
如果要输入 int 或 float 类型的数据,在 Scanner 类中也有支持,但是在输入之前最好先使用 hasNextXxx() 方法进行验证,再使用 nextXxx() 来读取。
hasNextInt()/nextInt():遇到空格时会停止读取,返回的结果为空格前读取到的部分。返回类型int。hasNextDouble()/nextDouble()
next() 和 nextLine() 连用时的注意事项next()、nextInt() 读取数据后指针还在当前行,如果紧跟 nextLine(),读取数据会出错。处理方法是:增多一个 nextLine()「吃掉」换行符即可。具体案例详看下文案例「单组字符串输入输出」。
如果全程只使用 nextInt() 不会有上述问题。
全是数字的话,使劲
nextInt()就行。
输入输出写法 StreamTokenizer+PrintWriter
如果你在各大 OJ 中出现部分样例时间超限(Time Limit Exceed,TLE),尝试换成以下输入输出写法。
1 | import java.io.*; |
输入形式
形式 A:单组/多组 + EOF/零尾模式
输入结束模式:
- EOF 结束模式:输入有多组,文件末尾即输入结束。
- 零尾模式:输入有多组,输入参数均为 0 时即输入结束。
给定两个整数 a 和 b ,请你求出 a+b 的值。
1 | ************************* EOF模式 *************************** |
1 | import java.util.Scanner; |
形式 B:T 组
给定两个整数 a 和 b ,请你求出 a+b 的值。
首先会给出一个数字 T,然后给出 T 组数字。
1 | 输入: |
1 | public static void main(String[] args) { |
形式 C:单组字符串的输出与输出
这里将探讨 nextInt() 和 nextLine() 混用的问题。
给定一个长度为 n 的字符串 s ,请你将其倒置,然后输出。
1 | 输入: |
1 | public static void main(String[] args) { |
注意到,上面的参考答案都统一使用了 nextLine() 函数读取输入。那么我们能不能用 nextInt() 与 nextLine() 混合读取呢?答案是可以的,但是容易出错。
1 | public static void main(String[] args) { |
我们发现 str 并没有读取成功,这是因为第一次在读取 nextInt() 时,指针还在当前行,第二个 nextLine() 只读取到一个换行符。解决方法是在读取 nextInt() 后,在上面代码中「位置 A」处使用 nextLine()「吃掉」第一行的换行符即可。
输出形式:字符串格式化 String.format
给定一个小数 n ,请你保留 3 位小数后输出。
如果原来的小数位数少于 3 ,需要补充 0 。
如果原来的小数位数多于 3 ,需要四舍五入到 3 位。
看到这题目时我还纳闷,以前在 LeetCode 刷题就好少这种返回指定精度数组并要求保留小数点后的 0 的,其实仔细想想以前刷题的核心代码模式要么返回 int 或 double,不需要我们处理输出的位数或补充 0。而这 ACM 模式输出的是 String,对输出自然会有另外的格式化要求。
1 | 输入: |
1 | public static void main(String[] args) { |
String.format 作为文本处理工具,为我们提供强大而丰富的字符串格式化功能。
对浮点数进行格式化:占位符格式为 %[index$][标识]*[最小宽度][.精度]转换符。
| 可用标识 | 可用转换符 |
|---|---|
- -,在最小宽度内左对齐,不可以与 0 标识一起使用。- 0,若内容长度不足最小宽度,则在左边用 0 来填充。- #,对 8 进制和 16 进制,8 进制前添加一个 0,16 进制前添加 0x。- +,结果总包含一个 + 或 - 号。- 空格,正数前加空格,负数前加 - 号。- ,,只用与十进制,每 3 位数字间用 , 分隔。- (,若结果为负数,则用括号括住,且不显示符号。 | - b,布尔类型,只要实参为非 false 的布尔类型,均格式化为字符串 true,否则为字符串 false。- n,平台独立的换行符, 也可通过 System.getProperty("line.separator") 获取。- f,浮点数型(十进制)。显示 9 位有效数字,且会进行四舍五入。如 99.99。- a,浮点数型(十六进制)。- e,指数类型。如 9.38e+5。- g,浮点数型(比 %f,%a 长度短些,显示 6 位有效数字,且会进行四舍五入) |
更多示例:
String.format("%09d",a):正整数不足 9 位的补充前导零。(🟩 单组_补充前导零_牛客题霸_牛客网 (nowcoder.com))





