CSP-J 考前复习
2025-10-28 16:09:46
发布于:上海
1 结构体排序
#include <bits/stdc++.h>
using namespace std;
int n;
struct stu {
string m;
int a, b;
}a[100];
int main() {
cin >> n;
int z = 0;
a[z].a = 0, a[z].b = 1e9;
for (int i = 1; i <= n; i++) {
cin >> a[i].m >> a[i].a >> a[i].b;
if (a[i].a >= a[z].a) {
z = i;//身高更高的奥特曼的下标
}
else if (a[i].a == a[z].a && a[i].b <= a[z].b) {
z = i;
}
}
cout << a[z].m << " " << a[z].a << " " << a[z].b;
return 0;
}
2 二分查找和二分答案
二分查找
lower_bound功能
返回第一个不小于给定值的元素位置(即第一个可以插入该值而不破坏顺序的位置)。
upper_bound功能
返回第一个大于给定值的元素位置。
使用:
int a[5] = {0, 1, 2, 3, 4};
//第一个参数:要查找范围的第一个数的地址
//第二个参数:要查找范围的最后一个数的 下一个 地址
//第三个参数:要查找的目标数字
int p = lower_bound(a + 0, a + 5, x) - a;
int p = upper_bound(a + 0, a + 5, x) - a;
二分答案
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int l[N], n, k;
// 检查是否可以将所有原木切割成长度为 mid 的小段,且总段数 >= k
bool check(int mid) {
int ans = 0;
for (int i = 1; i <= n; i++) {
ans += (l[i] / mid); // 每根原木可以切割的段数
}
return ans >= k;
}
// 二分搜索最大的 l
int bs(int l, int r) {
int ans = 0;
while (l <= r) {
int mid = (l + r) >> 1; // 取中间值
if (check(mid)) { // 如果满足条件,尝试更大的 l
ans = mid;
l = mid + 1;
} else { // 否则尝试更小的 l
r = mid - 1;
}
}
return ans;
}
int main() {
cin >> n >> k;
int maxn = 0;
for (int i = 1; i <= n; i++) {
cin >> l[i];
maxn = max(maxn, l[i]); // 记录最大原木长度
}
int l = 1;
int r = maxn;
int res = bs(l, r); // 二分搜索
cout << res;
return 0;
}
3 前缀和及其差分
前缀和
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e6 + 5;
int a[maxn], pre[maxn];
int main(){
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i ++){
cin >> a[i];
pre[i] = a[i] + pre[i - 1];
}
while (m --){
int l, r;
cin >> l >> r;
cout << pre[r] - pre[l - 1] << endl;
}
return 0;
}
差分
#include<iostream>
#include<algorithm>
using namespace std;
int n, p, a[5000005], d[50000005];
int main()
{
cin >> n >> p;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
d[i] = a[i] - a[i - 1];
}
for (int i = 1; i <= p; i++)
{
int x, y, z;
cin >> x >> y >> z;
d[x] += z;
d[y + 1] -= z;
}
for (int i = 1; i <= n; i++)
{
a[i] = d[i] + a[i - 1];
}
sort(a + 1, a + n + 1);
cout << a[1];
return 0;
}
4 双指针
[GESP202312四级] 田忌赛马_信奥算法普及-_GESP-ACGO题库
#include<bits/stdc++.h>
using namespace std;
int main() {
int n, sum = 0;
int a[10005];
int b[10005];
cin >> n;
for (int i = 1; i <= n; i++)cin >> a[i];
for (int i = 1; i <= n; i++)cin >> b[i];
sort(a + 1, a + n + 1);
sort(b + 1, b + n + 1);
int i = n, j = n;
while (i >= 1 && j >= 1) {
if (a[i] >= b[j]) {
sum++;
i--;
j--;
}
else {
j--;
}
}
cout << sum;
return 0;
}
5 埃式筛法
void Eratosthenes() {
//埃式筛
for (int i = 2; i <= sqrt(n); i++) {
if (vis[i] == 0) {
//vis[i]是素数,将vis[i]的素数设为1
for (int j = i * 2; j <= n; j += i) vis[j] = 1;
}
}
}
6 线性DP
(看另一篇文章,【线性DP】问题模型总结
7 深搜
(也看另一篇文章,【深搜】问题模型总结
8 广搜
#include <iostream>
#include <queue>
#include <vector>
#include <cstring>
using namespace std;
// 基础BFS模板
void bfs(int start) {
queue<int> q;
vector<bool> visited(n, false); // 访问标记数组
q.push(start);
visited[start] = true;
while (!q.empty()) {
int current = q.front();
q.pop();
// 处理当前节点
cout << current << " ";
// 遍历邻居节点
for (int neighbor : getNeighbors(current)) {
if (!visited[neighbor]) {
visited[neighbor] = true;
q.push(neighbor);
}
}
}
}
这里空空如也













有帮助,赞一个