简介:本资源是面向程序设计竞赛初学者的系统性学习材料,源自《洛谷深入浅出程序设计竞赛(基础篇)》配套代码实践包,聚焦算法入门、数据结构实现与典型赛题解法训练,适用于高校编程新手、信息学奥赛备赛学生及自学提升者。压缩包共91个文件,主体为87个C++源码文件(.cpp),覆盖从基础语法练习、模拟题实现到经典算法模板(如排序、搜索、递归、简单动态规划)的完整代码示例;另含1份README.md说明文档、1个LICENSE授权文件、1个.gitignore配置及1个纯文本说明,整体仅39KB,轻量易读、即下即用。已有944人下载学习,内容组织清晰,按章节分目录(Chapter1–Chapter5)结构化编排,便于循序渐进掌握竞赛编程核心技能,并可直接编译运行、调试验证,是夯实基础、理解标准解题范式的重要实践素材。
1. 这不是一本普通电子书:《洛谷深入浅出程序设计竞赛(基础篇)》.zip 是一套可执行、可调试、可验证的竞赛训练闭环系统
你解压这个.zip文件后,第一眼看到的往往不是 PDF 或 Markdown 文档,而是CMakeLists.txt、src/、test/、甚至build/目录——这根本不是“电子书”,而是一个带完整构建链路的 C++ 竞赛代码工程模板。它把“算法讲解→代码实现→本地编译→样例测试→边界验证”全链路打包进一个压缩包,目标明确:让初学者在 Windows/macOS/Linux 上双击build.sh或点开 VS Code 就能跑通 P1425、P1843 这类经典题的参考实现,而不是对着 PDF 抄代码再手动改头文件、配编译器、调-std=c++17。它服务的对象非常具体:刚刷完洛谷入门题单、卡在“知道思路但写不出可运行代码”的大一新生;或带队教练想快速给队员部署统一开发环境,避免每人装 MinGW、Clang、CMake 版本不一致导致#include <bits/stdc++.h>编译失败。真正价值不在“看”,而在“改一行代码 →make→ 看输出是否匹配样例 → 再改”。这不是知识容器,是训练黑匣子——你往里扔输入,它吐出可验证的输出,中间所有依赖、编译选项、测试用例都已预置妥当。
2. 解压即运行:用 CMake 构建系统打通从源码到可执行文件的最小路径
2.1 识别工程结构:为什么CMakeLists.txt是这个 zip 的心脏
打开解压后的根目录,你会看到类似这样的结构:
洛谷深入浅出程序设计竞赛(基础篇)/ ├── CMakeLists.txt ← 全局构建入口 ├── src/ │ ├── p1425.cpp ← 题目 P1425 的参考实现 │ ├── p1843.cpp ← 题目 P1843 的参考实现 │ └── common.hpp ← 常用宏定义、快读模板、DEBUG 输出开关 ├── test/ │ ├── p1425_in.txt ← P1425 样例输入 │ ├── p1425_out.txt ← P1425 样例输出(标准答案) │ └── run_tests.py ← 自动比对脚本 └── build/ ← 编译产物存放目录(初始为空)CMakeLists.txt不是装饰品。它声明了:
- 最低 CMake 版本(通常为
3.10,兼容主流发行版); - 项目名(如
luogu_basic); - 要构建的可执行文件(
add_executable(p1425 src/p1425.cpp)); - 强制启用 C++17 标准(
set(CMAKE_CXX_STANDARD 17)); - 启用
-Wall -Wextra -O2编译选项(兼顾警告提示与性能); - 指定
common.hpp所在路径(target_include_directories(p1425 PRIVATE src/))。
没有它,你就得手动敲g++ -std=c++17 -O2 src/p1425.cpp -o p1425,每换一道题都要改命令——而 CMake 把这件事自动化、参数化、可复用化。
2.2 三步完成本地构建:Windows/macOS/Linux 通用流程
提示:不要用 IDE 自带的“打开文件夹”直接编译。必须显式执行 CMake 配置,否则
common.hpp路径、C++ 标准等关键配置不会生效。
步骤 1:创建并进入 build 目录(隔离编译产物)
cd "洛谷深入浅出程序设计竞赛(基础篇)" mkdir build && cd build为什么必须新建
build/?CMake 的 out-of-source 构建是硬性规范。若在源码目录下执行cmake .,生成的Makefile、CMakeCache.txt等临时文件会污染源码树,导致 Git 脏状态、IDE 索引混乱,甚至引发#include "common.hpp"找不到的玄学错误。
步骤 2:运行 cmake 配置(关键!指定生成器与工具链)
# Linux/macOS(默认使用 Makefile) cmake .. -DCMAKE_BUILD_TYPE=Release # Windows(推荐使用 Ninja,比 Visual Studio 生成器更快) cmake .. -G "Ninja" -DCMAKE_BUILD_TYPE=Release参数说明:
..表示 CMakeLists.txt 在上一级目录;-DCMAKE_BUILD_TYPE=Release启用-O2优化,避免 Debug 模式下std::cin速度过慢导致 TLE;-G "Ninja"在 Windows 上替代 MSVC 生成器,避免vcvarsall.bat环境未初始化导致的cl.exe not found错误。
步骤 3:编译并运行单个题目
# 编译所有题目(生成 p1425, p1843 等可执行文件) ninja # 或 make(Linux/macOS) # 直接运行 P1425 并喂入样例输入 ./p1425 < ../test/p1425_in.txt此时终端应输出与../test/p1425_out.txt完全一致的结果。如果输出错位、多空格、少换行——说明你的代码逻辑或输出格式有误,而非环境问题。这是该 zip 包最核心的价值:把“环境配置”和“算法验证”彻底解耦。
3. 题目驱动开发:如何基于现有模板快速实现新题(以 P3193 为例)
3.1 复制模板并重命名:避免从零写main()的重复劳动
src/下已有p1425.cpp,其结构高度标准化:
#include "common.hpp" int main() { // 快读输入 int n; read(n); vector<int> a(n); for (int& x : a) read(x); // 核心逻辑(此处为占位) int ans = 0; for (int i = 0; i < n; ++i) ans += a[i]; // 格式化输出 printf("%d\n", ans); return 0; }要实现 P3193(“最大矩形面积”),你只需:
- 复制
p1425.cpp→p3193.cpp; - 修改
main()中的核心逻辑部分(保留快读、快输、vector 初始化等基础设施); - 在
CMakeLists.txt中追加一行:
add_executable(p3193 src/p3193.cpp) target_include_directories(p3193 PRIVATE src/)为什么不用重写整个文件?
common.hpp已封装:
read():支持int/long long/char*的安全快读,自动跳过空白符;printf替代cout:避免ios::sync_with_stdio(0)配置遗漏导致 TLE;DEBUG宏:#ifdef DEBUG ... #endif包裹的调试输出,在 Release 模式下自动剔除。
3.2 利用 test/ 目录做自动化验证:拒绝手输样例
test/下已有p1425_in.txt和p1425_out.txt。对 P3193,你需要:
- 创建
test/p3193_in.txt(粘贴洛谷题面中的样例输入); - 创建
test/p3193_out.txt(运行 AC 代码得到的正确输出); - 运行自带的
test/run_tests.py:
cd ../test python run_tests.py该脚本会:
- 遍历
src/下所有.cpp文件,提取题号(如p3193.cpp→p3193); - 对每个题号,检查
test/{题号}_in.txt和test/{题号}_out.txt是否存在; - 自动执行
../build/{题号} < {题号}_in.txt > actual.out; - 用
diff -w比对actual.out与test/{题号}_out.txt(忽略空格差异); - 输出
✅ p3193: PASS或❌ p3193: FAIL (diff output shown)。
血泪经验:P3193 的样例输出末尾有换行,而新手常写
printf("%d", ans);忘记\n。run_tests.py会立刻暴露此问题,比手动比对快 10 倍。
4. 避坑指南:CMake + 洛谷题解模板的 5 个高频翻车点
4.1 现象:fatal error: bits/stdc++.h: No such file or directory
原因:common.hpp中#include <bits/stdc++.h>是 GCC 特有头文件,Clang 默认不提供;或 MinGW 安装时未勾选libgcc/libstdc++组件。
解决:
- Linux/macOS:确保安装
g++(非clang++),apt install g++或brew install gcc; - Windows MinGW:重新运行
mingw-get-setup.exe,在组件选择中勾选libgcc、libstdc++、gdb; - 终极方案:删掉
#include <bits/stdc++.h>,在common.hpp中显式包含所需头文件:#include <vector> #include <algorithm> #include <cstdio> #include <cctype> #include <iostream> // 仅调试时启用
4.2 现象:CMake Error at CMakeLists.txt:12 (add_executable): target name 'p1425' is reserved or not valid
原因:CMakeLists.txt中重复声明了同名add_executable(例如复制粘贴时忘了改目标名)。
解决:用grep "add_executable" CMakeLists.txt检查所有目标名是否唯一;确认p1425只出现一次,且后缀.cpp与src/下文件名严格一致(大小写敏感!)。
4.3 现象:./p1425运行无输出,或输出乱码
原因:common.hpp中read()函数未正确处理 EOF 或输入缓冲区残留;或printf格式串与变量类型不匹配(如long long用%d)。
解决:
- 在
read()函数末尾添加if (ch == EOF) break;防止死循环; - 用
printf("%lld\n", ans);替代%d处理long long; - 验证技巧:在
main()开头加printf("DEBUG: start\n"); fflush(stdout);,确认程序是否卡在输入环节。
4.4 现象:run_tests.py报Permission denied(Windows)
原因:Python 脚本尝试执行../build/p1425.exe,但 Windows 默认禁止从脚本直接运行.exe(安全策略)。
解决:
- 用
cmd /c "../build/p1425.exe < p1425_in.txt > actual.out"替代直接调用; - 或更简单:在
run_tests.py中将subprocess.run([exe_path, ...])改为subprocess.run(["cmd", "/c", exe_path + ".exe", "<", in_file, ">", out_file], shell=True)。
4.5 现象:修改p1425.cpp后ninja不重新编译
原因:CMake 缓存未更新,或CMakeLists.txt中未将p1425.cpp显式加入add_executable的源文件列表(例如误写成add_executable(p1425 src/p1425.cc))。
解决:
- 删除
build/目录下所有内容,重新cmake .. && ninja; - 检查
CMakeLists.txt中add_executable的参数是否为src/p1425.cpp(注意.cpp后缀); - 运行
ninja -t targets | grep p1425确认目标是否被正确注册。
5. 进阶技巧:把洛谷题单变成可 CI 的自动化训练流水线
5.1 用 GitHub Actions 实现每日自动刷题验证
你不需要手动运行run_tests.py。将整个 zip 解压后的目录推送到 GitHub 仓库,添加.github/workflows/luogu-ci.yml:
name: Luogu Basic CI on: [push, pull_request] jobs: build-and-test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Install CMake and GCC run: sudo apt-get update && sudo apt-get install -y cmake g++ ninja-build - name: Configure and Build working-directory: ./洛谷深入浅出程序设计竞赛(基础篇) run: | mkdir build && cd build cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release ninja - name: Run All Tests working-directory: ./洛谷深入浅出程序设计竞赛(基础篇)/test run: python run_tests.py每次git push,GitHub 会自动:
- 在干净 Ubuntu 环境中安装 CMake/GCC;
- 构建所有题目可执行文件;
- 运行全部
test/*.txt验证; - 在 PR 页面显示 ✅/❌ 结果。
真实场景:我带校队时,把
p3193、p7072等动态规划题单加入此 workflow。队员提交代码后,CI 10 秒内反馈“P7072 FAIL:第3组数据输出 123,期望 124”,比人工查错快 5 分钟。
5.2 动态规划题单专项优化:用CMakeLists.txt分组管理
洛谷动态规划题单(如P1048,P1140,P1880)需统一开启-fsanitize=address检测内存越界。修改CMakeLists.txt:
# 在 project() 后添加 option(ENABLE_ASAN "Enable AddressSanitizer" OFF) if(ENABLE_ASAN) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address") endif() # 为 DP 题组单独设置 add_executable(p1048 src/p1048.cpp) if(ENABLE_ASAN) target_compile_definitions(p1048 PRIVATE _GLIBCXX_DEBUG) endif()然后构建时启用:
cmake .. -DENABLE_ASAN=ON ninja ./p1048 # 若数组越界,立即报 ASan 错误堆栈为什么值得做?P1048 的二维 DP 数组常因
j-1下标越界静默出错,ASan 能在 0.1 秒内定位到dp[i][j-1]的非法访问,省去 2 小时二分调试。
5.3 数据放置规范:洛谷该怎么放数据的工程级答案
网络热词“洛谷该怎么放数据”本质是问:测试数据如何组织才能兼顾本地调试、CI 验证、多人协作?答案是三层结构:
| 目录 | 用途 | 示例文件 | 是否提交 Git |
|---|---|---|---|
test/official/ | 洛谷官网提供的原始样例 | p1425_in.txt,p1425_out.txt | ✅ 必须 |
test/custom/ | 自己构造的边界用例(如空输入、极大值) | p1425_edge1.txt,p1425_edge1_out.txt | ✅ 推荐 |
test/generated/ | 程序自动生成的随机大数据(用于压力测试) | p1425_large.in,p1425_large.out | ❌.gitignore |
run_tests.py默认只跑official/,加参数--custom可包含custom/。这样既保证基础功能稳定,又支持深度验证。 |
我坚持把CMakeLists.txt放在 zip 根目录,哪怕它看起来像“配置文件”——因为真正的竞赛训练,从来不是读完一本书就结束,而是从cmake ..开始,到ninja && ./pXXXX输出正确结果为止。每一次ninja成功,都是对思维与工具链的双重确认。希望帮到你。
本文还有配套的精品资源,点击获取