OI 模板合集

发布时间 2023-07-27 09:41:50作者: 冬日潮汐A

此处存放本喵写过的各种 cpp 模板一共不时之需,不喜勿喷~

基本算法

for (int i = 1; i <= n; i ++) {
  cin >> arr[i];
  sum[i] = sum[i - 1] + arr[i];
}
前缀和
for (int i = 1; i <= n; i ++) {
    cin >> arr[i];
    dif[i] = arr[i] - arr[i - 1];
}
差分
int l = 0, r = 1e9, ans = 0;
while (l <= r) {
    int mid = (l + r) / 2;
    if (check(mid)) {
        ans = mid;
        r = mid - 1;
    } else {
        l = mid + 1;
    }
}
二分答案

基本数据结构

#include <bits/stdc++.h>
using namespace std;

int main() {
    int T;
    cin >> T;
    while (T--) {
        vector<unsigned long long> st;
        int n = 0;
        cin >> n;
        for (int i = 1; i <= n; i ++) {
            string op;
            unsigned long long x;
            cin >> op;
            if (op == "push") {
                cin >> x;
                st.push_back(x);
            } else if (op == "query") {
                if (st.size() != 0) {
                    cout << st.back() << endl;
                } else {
                    cout << "Anguei!" << endl;
                }
            } else if (op == "size") {
                cout << st.size() << endl;
            } else if (op == "pop") {
                if (st.size() != 0) {
                    st.pop_back();
                } else {
                    cout << "Empty" << endl;
                }
            }
        }
    }
    return 0;
}
#include <bits/stdc++.h>
using namespace std;

int main() {
    int N = 0;
    cin >> N;
    queue <int> q;
    while (N--) {
        int op = 0;
        cin >> op;

        if (op == 1) {
            int x = 0;
            cin >> x;
            q.push(x);
        } else if (op == 2) {
            if (q.size() == 0) {
                cout << "ERR_CANNOT_POP" << endl;
            } else {
                q.pop();
            }
        } else if (op == 3) {
            if (q.size() == 0) {
                cout << "ERR_CANNOT_QUERY" << endl;
            } else {
                cout << q.front() << endl;
            }
        } else {
            cout << q.size() << endl;
        }
    }
    return 0;
}
队列

搜索

// 暴力枚举所有方案
void dfs(int n, ...) {
    if (所有状态均枚举完成) {
       ...
       return; // 一定要返回
    }
    for (遍历当前状态所有扩展可能性) {
        if (判断扩展状态是否合法) {
            调整状态
            dfs(n + 1, ...); // 向深层递归搜索
            复原状态(一定要回溯!!)
        }
    }
}
深度优先搜索(伪代码)
// 用 vis 数组跳过已经走过的点(伪代码)
void dfs(int u) { // 当前的位置(节点)
    vis[u] = 1;
    for (与 u 相邻的节点 v) {
        if (!vis[v]) dfs(v);
    }
}
dfs(s); // 从起点开始
图上深度优先遍历(伪代码)
// 使用队列(伪代码)
void bfs() {
    queue<T> q;
    q.push(s); // 起点入队
    vis[s] = 1;
    while (!q.empty()) {
        T u = q.front();
        q.pop();
        for (与 u 相邻的节点 v) {
            if (!vis[v]) {
                q.push(v);
                vis[v] = 1; // 必须在此处标记,避免某节点多次入队
            }
        }
    }
}
图上广度优先遍历(伪代码)
#include <iostream>
#include <string>
#include <queue>
using namespace std;
int n, m;
string maze[110];
bool vis[110][110];
int dir[4][2] = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}};
bool in(int x, int y) {
    return 0 <= x && x < n && 0 <= y && y < m;
}

struct node {
    int x, y, d;
    node(int xx, int yy, int dd) { // 构造函数
        x = xx;
        y = yy;
        d = dd;
    }
};

int bfs(int sx, int sy) {
    queue<node> q;
    q.push(node(sx, sy, 0));
    vis[sx][sy] = true;
    while (!q.empty()) {
        node now = q.front();
        q.pop();
        for (int i = 0; i < 4; i ++) {
            int tx = now.x + dir[i][0];
            int ty = now.y + dir[i][1];
            if (in(tx, ty) and maze[tx][ty] != '*' and !vis[tx][ty]) {
                if (maze[tx][ty] == 'T') {
                    return now.d + 1;
                } else {
                    vis[tx][ty] = true;
                    q.push(node(tx, ty, now.d + 1));
                }
            }
        }
    }
    return -1;
}

int main() {
    cin >> n >> m;
    for (int i = 0; i < n; i++) {
        cin >> maze[i];
    }
    int x, y;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (maze[i][j] == 'S') {
                x = i, y = j;
            }
        }
    }

    cout << bfs(x, y) << endl;
    return 0;    
}
bfs 走迷宫
// (伪代码)
将 起始状态 和 目标结点 入队

标记起始结点为 1
标记目标结点为 2

while(队列不为空)
{
  从队首扩展出新个结点

  如果 新扩展出的结点已经被其他数字标记过,表示已经搜索到了一种方案,算法结束。

  如果新个结点是从起始状态扩展来的,那么将这个该结点标记 1 并入队

  如果新个结点是从目标结点扩展来的,那么将这个该结点标记 2 并入队
}
双向 bfs(伪代码)