复赛Linux操作流程
适用:CSP-J/S 第二轮 / NOIP / NOI 系列赛事
环境:NOI Linux 2.0(Ubuntu 20.04)
作者:CSP Editorial
一、为什么必须学 Linux 上机?
CSP 复赛全部在 Linux 环境下进行。很多同学平时在 Windows 上用 Dev-C++ 或 VS Code 写代码,到了考场连编译都不会,白白丢分。
这篇文章手把手带你走完 从登录到交卷 的全流程。
二、认识考场环境
2.1 桌面与终端
登录后你会看到一个 Ubuntu 桌面。最常用的两个工具:
- 文件管理器:浏览文件夹,类似 Windows 的资源管理器
- 终端(Terminal):输入命令的地方,比赛全程离不开它
右键桌面空白处 → 选择"在终端中打开",或者按快捷键 Ctrl + Alt + T。
2.2 选手目录
登录后默认在你的 用户主目录 下,路径是 /home/你的考号/。
建议在桌面建一个 code 文件夹,所有题目代码放里面:
mkdir ~/Desktop/code
cd ~/Desktop/code
三、C++ 代码编写与编译
3.1 用 gedit 写代码
考场自带 gedit(轻量文本编辑器),双击 .cpp 文件即可打开。
也可以从终端打开:
gedit task.cpp &
后面的 & 表示后台运行,终端不会被锁住。
3.2 编译命令
这是最重要的一行命令,务必背下来:
g++ -std=c++14 -O2 -Wall -o task task.cpp
| 参数 |
含义 |
-std=c++14 |
使用 C++14 标准(NOI 官方指定) |
-O2 |
开启 O2 优化 |
-Wall |
显示所有警告(帮你提前发现 bug) |
-o task |
输出文件名为 task |
task.cpp |
你的源代码文件 |
⚠️ 不要省略 -Wall!很多隐藏的错误(比如变量未初始化)靠它发现。
3.3 运行程序
./task
如果程序需要输入,可以手动敲,也可以重定向(见下一章)。
四、文件输入输出(决定你 0 分还是 100 分)
4.1 比赛要求
复赛必须使用文件读写!题目会告诉你输入文件名和输出文件名,比如:
4.2 freopen 写法(推荐)
在 main() 函数最开头加两行:
#include <cstdio>
int main() {
freopen("task.in", "r", stdin);
freopen("task.out", "w", stdout);
// 你的代码
int a, b;
scanf("%d%d", &a, &b);
printf("%d\n", a + b);
fclose(stdin);
fclose(stdout);
return 0;
}
🔑 记牢口诀:freopen 必须写在 main 最前面,读用 "r",写用 "w"。
4.3 测试技巧
在终端用重定向快速测试:
# 方法一:重定向(不用改代码,适合本地调试)
./task < task.in
# 方法二:freopen(与考试一致,推荐)
./task
diff task.out task.ans # 对比你的输出和标准答案
五、常用 Linux 命令速查
| 命令 |
作用 |
示例 |
ls |
列出当前目录文件 |
ls -l 看详细信息 |
cd |
切换目录 |
cd ~/Desktop/code |
pwd |
显示当前路径 |
pwd |
cp |
复制文件 |
cp a.cpp b.cpp |
mv |
移动/重命名 |
mv old.cpp new.cpp |
rm |
删除文件 |
rm temp.cpp |
mkdir |
创建文件夹 |
mkdir backup |
cat |
查看文件内容 |
cat task.in |
diff |
对比两个文件 |
diff a.out b.out |
time |
测运行时间 |
time ./task < task.in |
⚠️ rm 删除的文件不可恢复,删前确认!
六、对拍(确保代码正确)
写完代码不确定对不对?用对拍验证。
步骤:
对拍脚本参考:
#!/bin/bash
g++ -std=c++14 -O2 -o my my.cpp # 你的程序
g++ -std=c++14 -O2 -o brute brute.cpp # 暴力程序
g++ -std=c++14 -O2 -o gen gen.cpp # 数据生成器
for ((i=1; i<=1000; i++)); do
./gen > data.in
./my < data.in > my.out
./brute < data.in > brute.out
diff my.out brute.out
if [ $? -ne 0 ]; then
echo "WA on test $i"
break
fi
echo "Test $i OK"
done
保存为 check.sh,终端运行 bash check.sh。
七、常见错误与解决方案
| 错误 |
原因 |
解决 |
command not found |
命令拼写错误或未安装 |
检查拼写,或 apt install xxx |
Permission denied |
文件没有执行权限 |
chmod +x ./task |
Segmentation fault |
数组越界或访问非法内存 |
检查数组大小,检查指针 |
| 编译通过但输出为空 |
忘记 freopen 或文件名错误 |
检查文件名是否与题目一致 |
diff 无差异但评测 0 分 |
freopen 把 stdout 和 stderr 都写入了文件 |
确认只重定向 stdin/stdout |
八、交卷前检查清单
- 编译命令带了
-std=c++14 -O2 -Wall? - 数组开得够大?(一般开到题目最大规模的 1.1 倍)
- 递归深度大时加了
-Wl,--stack=xxx?
九、一条龙流程总结
1. 开终端 → cd ~/Desktop/code
2. gedit task.cpp & → 写代码(加 freopen)
3. 保存 → g++ -std=c++14 -O2 -Wall -o task task.cpp
4. 如果有错 → 根据错误信息修改 → 重新编译
5. ./task → 手动测试样例
6. diff task.out task.ans → 确认输出正确
7. 造几组边界数据再测 → 无误后下一题
8. 全部做完 → 逐题检查 freopen 文件名 ⚠️
考试比的是心态和细节。Linux 操作流程熟了,考场上才能专注于解题本身。
下一篇预告:递归入门——边界、递推、回溯三要素