面向零基础的完整讲解:每讲都有知识点、可运行的代码模板、经典例题和练习指引。
建议节奏:每天一讲 + 当天完成对应练习;13 天走完基础盘,然后按最后一讲的刷题路线持续推进。
不会注册?第 1 讲里写了每一步。做题时遇到不会的,先看最后一讲的"卡住了怎么办"。
#include <bits/stdc++.h>
using namespace std;
int main(){
int a, b;
cin >> a >> b; // 读入两个数
cout << a + b << endl; // 输出它们的和
return 0;
}
竞技编程的第一思维不是"对不对",而是"快不快"。评测机大约每秒能执行 1 亿次左右的基本操作。
// 求 1+2+...+n
// 慢:循环 O(n)
long long s = 0;
for (int i = 1; i <= n; i++) s += i;
// 快:公式 O(1)
long long s2 = 1LL * n * (n + 1) / 2;
int a[100005]; 开在外层(全局)会自动清零且不会爆栈。string s; 支持 s.size()、s[i]、s.substr(l, len)。string s; getline(cin, s);
int cnt = 0;
for (char c : s)
if (c >= 'A' && c <= 'Z') cnt++;
cout << cnt << endl;
int a[1005], n;
sort(a, a + n); // 升序
sort(a, a + n, greater<int>()); // 降序
// 结构体排序
struct P { int x, y; };
bool cmp(const P& a, const P& b){ return a.x < b.x; }
sort(p, p + m, cmp);
两种用法:一、 在有序数组里找某个值;二、 答案具有单调性时二分答案("最大的最小值""能不能做到"类问题)。
// 在升序数组 a 里找 x 是否存在
int l = 0, r = n - 1;
while (l <= r) {
int mid = (l + r) / 2;
if (a[mid] == x) { /* 找到 */ break; }
if (a[mid] < x) l = mid + 1; else r = mid - 1;
}
long long pre[100005];
for (int i = 1; i <= n; i++) pre[i] = pre[i-1] + a[i];
// 区间 [l, r] 的和:
long long ans = pre[r] - pre[l-1];
// 让 [l, r] 全部 +v:
diff[l] += v; diff[r+1] -= v;
// 结束后求前缀和还原:
for (int i = 1; i <= n; i++) a[i] = a[i-1] + diff[i];
nxt[i]),用于频繁插入删除。// 括号匹配
stack<char> st; bool ok = true;
for (char c : s) {
if (c == '(') st.push(c);
else if (c == ')') {
if (st.empty()) { ok = false; break; }
st.pop();
}
}
if (!st.empty()) ok = false;
cout << (ok ? "YES" : "NO") << endl;
// 求 n 的阶乘(最简单的递归)
long long fac(int n) {
if (n <= 1) return 1; // 终止
return n * fac(n - 1); // 缩小规模
}
// DFS 框架(网格)
int n, m; bool vis[1005][1005];
int dx[4] = {1, -1, 0, 0}, dy[4] = {0, 0, 1, -1};
void dfs(int x, int y) {
vis[x][y] = true;
for (int k = 0; k < 4; k++) {
int nx = x + dx[k], ny = y + dy[k];
if (nx >= 0 && nx < n && ny >= 0 && ny < m && !vis[nx][ny])
dfs(nx, ny);
}
}
第 8–13 讲(BFS、贪心、动态规划入门、图论入门、并查集与最小生成树、刷题路线图)在下方继续……
也可直接跳到:继续学习第 8–13 讲 →(如果页面太长,分页版在这里)