C++ 速查参考 - we1c0me t0 PurgationDevil 810g

C++ 速查参考

Posted by PurgationDevil Blog on April 12, 2026

模板

1
2
3
4
5
6
7
8
9
10
11
#include <bits/stdc++.h>// 仅比赛用,其他情况下不建议也可能不支持使用
using namespace std;// 大项目程序不建议使用

int main() {
    ios::sync_with_stdio(false); // 加速 禁用stdio.h的代码(C++98不支持使用)
    cin.tie(nullptr);            // 加速 cin与cout分离
    
    // 代码
    
    return 0;
}

输入与输出

基本输入输出

操作 代码 说明
读整数 cin >> n; 自动跳过空格/换行
读字符串 cin >> s; 读到空格停止
忽略换行符 cin.ignore(); 避免后面的getline(cin, s);跳过
读整行 getline(cin, s); 读入空格,前面有cin需加cin.ignore()
读到,停止 getline(cin, s, ','); 逗号可以换成其他
输出 cout << x;  
换行 cout << endl;cout << "\n";  

常见输入模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 先读n,再读n个数
int n; cin >> n;
vector<int> a(n);
for (int i = 0; i < n; i++) cin >> a[i];

// 读到文件尾
int x;
while (cin >> x) { ... }

// 读带逗号的数据
int a, b;
char comma;
cin >> a >> comma >> b;  // 输入 "1,2"

// 读坐标 (x,y)
int x, y;
char ch;
cin >> ch >> x >> ch >> y >> ch;  // ch 吃掉括号和逗号

输出格式控制(iomanip)

控制符 作用 示例
setw(n) 设置宽度为 n cout << setw(5) << 123;" 123"
setfill(c) 设置填充字符 cout << setfill('0') << setw(5) << 123;"00123"
setprecision(n) 设置小数精度 cout << setprecision(2) << 3.14159;3.1(默认模式)
fixed 固定小数位数 cout << fixed << setprecision(2) << 3.14159;3.14
scientific 科学计数法 cout << scientific << 3.14159;3.141590e+00
left / right 左对齐/右对齐 cout << left << setw(5) << 123;"123 "
hex / dec / oct 十六进制/十进制/八进制 cout << hex << 255;"ff"
showbase 显示进制前缀 cout << showbase << hex << 255;"0xff"
uppercase 十六进制大写 cout << uppercase << hex << 255;"FF"
boolalpha 输出 true/false cout << boolalpha << true;"true"

常用 <cmath> 函数速查

幂函数、指数函数与对数

函数 作用 代码示例
sqrt(x) 计算平方根 double result = sqrt(9.0); // 结果为 3.0
pow(x, y) 计算 x 的 y 次方 double result = pow(2.0, 3.0); // 结果为 8.0
exp(x) 计算 e 的 x 次方 double result = exp(1.0); // 结果为 e (约 2.71828)
log(x) 计算自然对数(以 e 为底) double result = log(2.71828); // 结果约等于 1.0
log10(x) 计算常用对数(以 10 为底) double result = log10(100.0); // 结果为 2.0

取整与绝对值

函数 作用 代码示例
fabs(x) 计算浮点数的绝对值 double result = fabs(-3.14); // 结果为 3.14
abs(x) 计算整数的绝对值 int result = abs(-5); // 结果为 5
ceil(x) 向上取整 double result = ceil(2.3); // 结果为 3.0
floor(x) 向下取整 double result = floor(2.7); // 结果为 2.0
round(x) 四舍五入取整 double result = round(2.5); // 结果为 3.0

三角函数与反三角函数

函数 作用 代码示例
sin(x) / cos(x) / tan(x) 正弦 / 余弦 / 正切(x 为弧度) double result = sin(3.14159 / 2); // 结果约等于 1.0
asin(x) / acos(x) / atan(x) 反正弦 / 反余弦 / 反正切 double result = asin(1.0); // 结果约等于 π/2 (1.5708)
atan2(y, x) 计算 y/x 的反正切(可确定象限) double result = atan2(1.0, 1.0); // 结果约等于 π/4 (0.785)

其他常用函数

函数 作用 代码示例
fmod(x, y) 计算 x/y 的浮点数余数 double result = fmod(5.2, 2.0); // 结果为 1.2
hypot(x, y) 计算直角三角形斜边长 (√x²+y²) double result = hypot(3.0, 4.0); // 结果为 5.0

类和对象

类与对象的关系

概念 比喻 代码
设计图纸 class Student { ... };
对象 根据图纸造出的房子 Student s;
成员变量 房子的属性 string name; int age;
成员函数 房子的功能 void study();

定义一个简单的类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <string>
using namespace std;

class Student {
public:                      // 公共访问权限
    string name;
    int age;
    
    void introduce() {
        cout << "我叫" << name << ",今年" << age << "岁" << endl;
    }
};

int main() {
    Student s1;
    s1.name = "张三";
    s1.age = 18;
    s1.introduce();          // 我叫张三,今年18岁
    return 0;
}

访问权限(封装)

关键字 含义 访问范围
public 公开 类内、类外都能访问
private 私有 只能在类内访问(默认
protected 保护 类内和子类能访问
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Student {
private:                     // 私有成员
    string name;
    int age;
    
public:                      // 公有接口
    void setName(string n) { name = n; }
    string getName() { return name; }
    void setAge(int a) { 
        if (a >= 0 && a <= 150) age = a;
        else cout << "年龄无效" << endl;
    }
    int getAge() { return age; }
};

int main() {
    Student s;
    // s.name = "张三";   // ❌ 错误,name是private
    s.setName("张三");      // ✅ 通过公有函数设置
    cout << s.getName();    // ✅ 通过公有函数获取
    return 0;
}

构造函数(创建对象时自动调用)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Student {
private:
    string name;
    int age;
    
public:
    // 构造函数:与类同名,无返回值
    Student(string n, int a) {
        name = n;
        age = a;
        cout << "学生" << name << "已创建" << endl;
    }
    
    void introduce() {
        cout << "我是" << name << "," << age << "岁" << endl;
    }
};

int main() {
    Student s1("张三", 18);   // 自动调用构造函数
    Student s2("李四", 19);
    s1.introduce();
    return 0;
}

构造函数重载

1
2
3
4
5
6
7
8
9
10
class Student {
private:
    string name;
    int age;
    
public:
    Student() : name("无名"), age(0) {}               // 无参构造
    Student(string n) : name(n), age(18) {}           // 单参构造
    Student(string n, int a) : name(n), age(a) {}     // 双参构造
};

初始化列表(推荐写法)

1
2
3
4
Student(string n, int a) : name(n), age(a) {
    // 函数体可以为空
}
// 优点:效率更高,const成员和引用成员必须用初始化列表

析构函数(对象销毁时自动调用)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Array {
private:
    int* data;
    int size;
    
public:
    Array(int n) : size(n) {
        data = new int[n];      // 构造函数分配堆内存
    }
    
    ~Array() {                  // 析构函数:前面加 ~
        delete[] data;          // 释放内存
        cout << "内存已释放" << endl;
    }
};

int main() {
    Array arr(100);             // 创建
    // ...
    return 0;                   // 离开作用域,自动调用析构函数
}

this 指针

this 指向当前对象自己。

1
2
3
4
5
6
7
8
9
class Student {
private:
    string name;
    
public:
    void setName(string name) {
        this->name = name;      // 区分成员变量和参数
    }
};

静态成员(属于类,所有对象共享)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Student {
private:
    string name;
    static int count;           // 静态成员变量(声明)
    
public:
    Student(string n) : name(n) {
        count++;                // 每创建一个学生,计数+1
    }
    
    static int getCount() {     // 静态成员函数
        return count;
    }
};

int Student::count = 0;         // 静态成员变量定义(必须)

int main() {
    Student s1("张三");
    Student s2("李四");
    cout << Student::getCount() << endl;   // 2
    return 0;
}

STL

容器(Containers)

1. vector(动态数组)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <vector>
vector<int> v;

// 初始化
vector<int> v;                    // 空
vector<int> v(n);                 // n个0
vector<int> v(n, x);              // n个x
vector<int> v = {1,2,3};          // 列表初始化

// 操作
v.push_back(x);      // 尾部加
v.pop_back();        // 尾部删
v[i] = x;            // 下标访问(不检查越界)
v.at(i);             // 下标访问(检查越界)
v.size();            // 长度
v.empty();           // 判空
v.clear();           // 清空
v.resize(n);         // 重设大小
v.begin(); v.end();  // 迭代器

// 遍历
for (int i = 0; i < v.size(); i++) cout << v[i];
for (int x : v) cout << x;
for (auto it = v.begin(); it != v.end(); it++) cout << *it;

2. deque(双端队列)

1
2
3
4
5
6
7
8
9
#include <deque>
deque<int> dq;

dq.push_back(x);     // 尾部加
dq.push_front(x);    // 头部加
dq.pop_back();       // 尾部删
dq.pop_front();      // 头部删
dq[i];               // 下标访问
dq.size(); dq.empty(); dq.clear();

3. stack(栈,后进先出)

1
2
3
4
5
6
7
8
#include <stack>
stack<int> st;

st.push(x);      // 压栈
st.pop();        // 出栈(无返回值)
st.top();        // 查看栈顶
st.size(); st.empty();
// 注意:stack 不能直接遍历

4. queue(队列,先进先出)

1
2
3
4
5
6
7
8
#include <queue>
queue<int> q;

q.push(x);       // 入队
q.pop();         // 出队(无返回值)
q.front();       // 队头
q.back();        // 队尾
q.size(); q.empty();

5. priority_queue(优先队列,最大堆)

1
2
3
4
5
6
7
8
#include <queue>
priority_queue<int> pq;                    // 大根堆
priority_queue<int, vector<int>, greater<int>> pq2;  // 小根堆

pq.push(x);      // 插入
pq.pop();        // 删除堆顶
pq.top();        // 查看堆顶
pq.size(); pq.empty();

6. set(集合,自动去重+排序)

1
2
3
4
5
6
7
8
9
10
11
12
#include <set>
set<int> s;
set<int, greater<int>> s2;   // 降序

s.insert(x);     // 插入
s.erase(x);      // 按值删除
s.count(x);      // 判断存在(0或1)
s.find(x);       // 查找,返回迭代器
s.size(); s.empty(); s.clear();

// 遍历
for (int x : s) cout << x;

7. map(映射,键自动排序)

1
2
3
4
5
6
7
8
9
10
11
12
#include <map>
map<string, int> mp;

mp[key] = value;     // 插入/修改
mp.count(key);       // 判断键存在
mp.erase(key);       // 删除
mp.size(); mp.empty(); mp.clear();

// 遍历
for (auto& p : mp) {
    cout << p.first << ":" << p.second;
}

8. unordered_set / unordered_map(哈希表,O(1))

1
2
3
4
5
6
7
#include <unordered_set>
#include <unordered_map>

unordered_set<int> us;
unordered_map<string, int> ump;

// 操作同 set/map,但不排序,更快

9. pair(对组)

1
2
3
4
5
6
7
#include <utility>
pair<int, int> p = {x, y};
pair<int, int> p2 = make_pair(x, y);

p.first;   p.second;    // 访问

// pair 可直接比较、排序(先first,再second)

迭代器(Iterators)

基本操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
vector<int> v = {1,2,3,4,5};

auto it = v.begin();    // 指向第一个元素
auto end = v.end();     // 指向最后一个的下一个位置

*it;           // 解引用
it++; it--;    // 移动
it + 2;        // 随机移动(vector/deque支持)

// 遍历
for (auto it = v.begin(); it != v.end(); it++) {
    cout << *it;
} // cpp11+版本
for (vector<int>::iterator it = v.begin(); it != v.end(); it++){
    cout << *it;
} // 老版本

迭代器失效

操作 vector list/set/map
插入 可能全失效 不失效
删除 后面全失效 只失效被删的
扩容 全部失效 -
1
2
3
4
5
// 正确删除写法
for (auto it = v.begin(); it != v.end(); ) {
    if (需要删除) it = v.erase(it);
    else it++;
}

算法(Algorithms)

头文件

1
2
#include <algorithm>
#include <numeric>

遍历

1
2
3
4
5
6
7
8
for_each(v.begin(), v.end(), [](int x){
    cout << x;
});
// 使用transform前一定要用b.resize(a.size())扩大空间
v2.resize(v.size())
transform(v.begin(), v.end(), v2.begin(), [](int x){
    x += 1;
})

排序

1
2
3
4
5
6
7
8
sort(v.begin(), v.end());                              // 升序
sort(v.begin(), v.end(), greater<int>());              // 降序
sort(v.begin(), v.end(), [](int a, int b) {            // 自定义
    return a > b;
});
stable_sort(...);   // 稳定排序
partial_sort(...);  // 部分排序
nth_element(...);   // 找第n大

查找

1
2
3
4
5
auto it = find(v.begin(), v.end(), x);                 // 线性查找
bool ok = binary_search(v.begin(), v.end(), x);        // 二分(有序,超快)
int pos = lower_bound(v.begin(), v.end(), x) - v.begin();  // 第一个 >= x
int pos = upper_bound(v.begin(), v.end(), x) - v.begin();  // 第一个 > x
auto range = equal_range(v.begin(), v.end(), x);       // 返回 {lower, upper}

修改

1
2
3
4
5
reverse(v.begin(), v.end());        // 反转
fill(v.begin(), v.end(), 0);        // 填充
replace(v.begin(), v.end(), old, new);  // 替换
copy(v.begin(), v.end(), back_inserter(v2));  // 复制
rotate(v.begin(), v.begin()+k, v.end());  // 旋转

删除(erase-remove 惯用法)

1
2
3
4
5
// 删除所有值为 x 的元素
v.erase(remove(v.begin(), v.end(), x), v.end());

// 删除满足条件的元素
v.erase(remove_if(v.begin(), v.end(), [](int x){ return x < 0; }), v.end());

排序去重

1
2
sort(v.begin(), v.end());
v.erase(unique(v.begin(), v.end()), v.end());

计数

1
2
3
4
int cnt = count(v.begin(), v.end(), x);                // 等于x的个数
int cnt = count_if(v.begin(), v.end(), [](int x){      // 满足条件的个数
    return x > 0;
});

最值

1
2
3
int mx = *max_element(v.begin(), v.end());
int mn = *min_element(v.begin(), v.end());
auto [min, max] = minmax_element(v.begin(), v.end());  // C++11

数值(numeric)

1
2
3
4
5
6
7
8
int sum = accumulate(v.begin(), v.end(), 0);           // 求和
int sum = accumulate(v.begin(), v.end(), 0LL);         // long long 求和
int prod = accumulate(v.begin(), v.end(), 1, multiplies<int>());  // 乘积

vector<int> prefix(v.size());
partial_sum(v.begin(), v.end(), prefix.begin());       // 前缀和

iota(v.begin(), v.end(), 1);        // 填充 1,2,3,4,5...

排列

1
2
3
4
5
6
next_permutation(v.begin(), v.end());  // 下一个排列,返回false表示最后一个
prev_permutation(v.begin(), v.end());  // 上一个排列

do {
    // 处理当前排列
} while (next_permutation(v.begin(), v.end()));

集合操作(要求有序)

1
2
3
4
5
6
7
vector<int> res;
set_union(a.begin(), a.end(), b.begin(), b.end(), back_inserter(res));
set_intersection(...);
set_difference(...);
set_symmetric_difference(...);
// back_inserter(res)是一个插入迭代器,每次写入时自动调用 res.push_back(),所以不需要提前分配空间。否则使用merge前一定要用v.resize(a.size() + b.size())扩大空间。
merge(a.begin(), a.end(), b.begin(), b.end(), back_inserter(res));

堆操作

1
2
3
4
make_heap(v.begin(), v.end());       // 建堆
push_heap(v.begin(), v.end());       // 入堆(先push_back)
pop_heap(v.begin(), v.end());        // 出堆(再pop_back)
sort_heap(v.begin(), v.end());       // 堆排序

算术仿函数

头文件#include <functional>

常用的算术仿函数

仿函数 运算 示例
plus<T> 加法 + plus<int>()(3, 5) → 8
minus<T> 减法 - minus<int>()(5, 3) → 2
multiplies<T> 乘法 * multiplies<int>()(3, 5) → 15
divides<T> 除法 / divides<int>()(10, 2) → 5
modulus<T> 取模 % modulus<int>()(10, 3) → 1
negate<T> 取反 - negate<int>()(5) → -5

实际应用场景

配合 accumulate 求和

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <vector>
#include <numeric>
#include <functional>
using namespace std;

int main() {
    vector<int> v = {1, 2, 3, 4, 5};
    
    // 默认求和
    int sum = accumulate(v.begin(), v.end(), 0);
    
    // 用 plus 显式求和(等价)
    int sum2 = accumulate(v.begin(), v.end(), 0, plus<int>());
    
    // 求乘积
    int product = accumulate(v.begin(), v.end(), 1, multiplies<int>());
    
    cout << "和:" << sum << endl;        // 15
    cout << "积:" << product << endl;    // 120
    
    return 0;
}

配合 transform 批量运算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;

int main() {
    vector<int> a = {1, 2, 3, 4, 5};
    vector<int> b = {10, 20, 30, 40, 50};
    vector<int> result(a.size());
    
    // 对应位置相加
    transform(a.begin(), a.end(), b.begin(), result.begin(), plus<int>());
    // result = {11, 22, 33, 44, 55}
    
    // 对应位置相乘
    transform(a.begin(), a.end(), b.begin(), result.begin(), multiplies<int>());
    // result = {10, 40, 90, 160, 250}
    
    return 0;
}

配合 sort 排序(虽然更常用 greater/less

1
2
3
4
5
// 降序排序
sort(v.begin(), v.end(), greater<int>());

// 升序排序
sort(v.begin(), v.end(), less<int>());

greaterless 也是仿函数,不过它们属于关系仿函数(比较大小),不是算术仿函数。


常用比赛技巧

类型别名

1
2
3
4
using ll = long long;
using pii = pair<int, int>;
using vi = vector<int>;
using vvi = vector<vector<int>>;

二维 vector

1
2
3
4
5
6
7
8
9
10
// 定义 n 行 m 列,全 0
vector<vector<int>> a(n, vector<int>(m));

// 定义 n 行 m 列,全 -1
vector<vector<int>> b(n, vector<int>(m, -1));

// 输入
for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++)
        cin >> a[i][j];

字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
string s = "hello";
s.length(); s.size();           // 长度
s.empty();                      // 判空
s += "world";                   // 拼接
s.substr(pos, len);             // 截取
s.find("ell");                  // 查找,返回下标,找不到返回 string::npos
s.find('e');
if (s.find('x') != string::npos) { ... }

// 转换
stoi("123");      // string → int
stoll("123");     // string → long long
to_string(123);   // int → string

// 判断
isdigit(c); isalpha(c); islower(c); isupper(c);

二分(在有序数组上)

1
2
3
4
5
6
7
// 在 vector 上
int pos = lower_bound(v.begin(), v.end(), x) - v.begin();
int pos = upper_bound(v.begin(), v.end(), x) - v.begin();

// 在普通数组上
int* p = lower_bound(a, a + n, x);
int pos = p - a;

常用常量

1
2
3
int INF = 0x3f3f3f3f;           // 约 1e9
long long LINF = 0x3f3f3f3f3f3f3f3f;
int MOD = 1e9 + 7;

比赛检查清单

  • #include <bits/stdc++.h> 或需要的头文件
  • using namespace std;
  • int main() 不是 void main
  • return 0;
  • 加速 ios::sync_with_stdio(false); cin.tie(nullptr);
  • 变量初始化(int sum = 0
  • 数组/vector 大小正确
  • 输出格式(空格、换行)
  • 数据类型(int 够不够?要 long long 吗?)
  • 边界条件(n=0, n=1)

比赛常见错误

错误 原因 解决
编译错误 变量名拼错、少头文件 看第一行错误信息
运行错误 数组越界、除以0、栈溢出 检查下标、递归深度
答案错误 输出格式、数据类型 检查空格换行、用long long
超时 循环太多 用二分/set/map优化