竞赛代码模板

算法竞赛通用代码模板的结构与使用方法

一句话工具

竞赛代码模板是一份“开题骨架”:先放好头文件、类型别名、调试宏、快读快写和主函数结构,写题时只补核心逻辑。

模板解决的问题

比赛时每道题都要重复写一些固定内容:

  • 头文件和命名空间。
  • 常用类型别名。
  • 全局数组和常量。
  • 输入函数。
  • 调试输出。
  • main 函数骨架。

这些内容本身不难,但重复手写会浪费注意力,也容易出现细小错误。通用模板的目标是把这些固定部分提前准备好,让写题时把精力放在建模和核心算法上。

模板结构

当前模板大致分成五块:

  1. 文件头信息:记录作者、题目、OJ、描述等。
  2. 基础环境:bits/stdc++.husing namespace stdtypedef long long ll
  3. 调试宏:本地开启,提交时可用 ONLINE_JUDGENO_DEBUG 屏蔽。
  4. 全局数据区:常量、数组、nm 等常见变量。
  5. 主函数骨架:读入、处理、输出。

其中 quickIO 通过模板引用接入:

cpp
        
1
{{include "code/utils/quick_io.cpp"}}

如果你的代码模板系统会展开这个引用,就能自动把快读快写插入当前位置;如果只是手动复制,则需要把 quickIO 对应代码一并复制进去。

使用步骤

  1. 复制通用模板。
  2. 根据题目替换文件头里的 ojtitledescription 等占位信息。
  3. 修改 maxn、全局数组和读入变量。
  4. init 或对应位置读入数据。
  5. main 中补上核心算法流程。
  6. 提交前确认调试输出已关闭。

代码实现

模板文件位置:/code/template/template.cpp

cpp
        
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/** * Author by {{author}} blog: {{blog}} github : {{github}} * date: {{date}} * oj: {{oj}} * title: {{title}} * description: {{description}} */ #include <bits/stdc++.h> using namespace std; typedef long long ll; // #define NO_DEBUG // switch debug #if defined(onlinejudge) || defined(ONLINE_JUDGE) || defined(NO_DEBUG) #define log(...) #define fenc #else #define log(args...) { cout << "LINE:" << __LINE__ << " : ";string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); } #define fenc cout<<"================================"; void err(istream_iterator<string> it) {} template<typename T> void err(istream_iterator<string> it, T a) { cerr << *it << " = " << a << "\n"; } template<typename T, typename... Args> void err(istream_iterator<string> it, T a, Args... args) { cerr << *it << " = " << a << ", "; err(++it, args...); } #endif const int maxn = 1e6+5; int n,m; int a[maxn]; {{include "code/utils/quick_io.cpp"}} void init() { read(n); CURRENT_LINE } signed main () { #ifdef FREOPEN freopen("in", "r",stdin); #endif // std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); // 关闭io同步 return 0; }

常见改法

不使用 quickIO

如果题目输入规模不大,可以删除 quickIO 引用,改用标准流:

cpp
        
1
2
ios::sync_with_stdio(false); cin.tie(nullptr);

这样代码更短,也更适合字符串、浮点数、混合输入等场景。

调整调试宏

模板里通过 NO_DEBUGONLINE_JUDGE 控制调试输出。常见做法是本地默认开启,提交时自动关闭:

cpp
        
1
2
3
#if defined(ONLINE_JUDGE) #define log(...) #endif

如果某个 OJ 没有定义 ONLINE_JUDGE,可以在提交前手动加上:

cpp
        
1
#define NO_DEBUG

改成多测试用例结构

如果题目有多组数据,可以把核心逻辑封装成 solve()

cpp
        
1
2
3
4
5
6
7
8
9
10
11
void solve() { // read one test case // solve one test case } int main() { int T; read(T); while (T--) solve(); return 0; }

注意事项

  • 通用模板不是越大越好,只保留高频、低风险、你真的熟悉的内容。
  • maxn 要按题目约束调整,避免数组过小越界,也避免盲目开过大的全局数组。
  • 如果模板里含有占位符,提交前必须替换干净。
  • 调试宏不要把信息输出到正式答案里。
  • 不同题目的输入输出特点不同,quickIO 和标准流不要机械套用。

维护方式

后续如果要修改通用头文件、常用类型别名、输入输出设置,请直接修改上面的代码文件。文章只负责解释模板的结构和使用方法,真正可复制的代码以 book/code/template/template.cpp 为准。