算法竞赛个人注意事项

浅浅记录一下自己在算法竞赛中的注意事项。

数据类

注意看数大小,数学库中的函数尽量加上 * 1.0转成double,防止整型溢出。int型相乘如果可能溢出,乘 * 1LL

数据范围大于1e6,注意用快读。

浮点数输入输出:

cpp 复制代码
少用float
scanf("%lf", &d);
printf("%.f",d)

取模,注意取成负数的情况。

int,但是数据太大,全转long long

cpp 复制代码
#include <iostream>
using namespace std;
#define int lnog long
signed main() // 注意 int -> signed
{
}

行末无空格

cpp 复制代码
cout<<data<<" \n"[i == n];

数据存储尽量不要自定义struct或者class,善于使用pair,array等,防止需要重载什么的,导致代码层面的错误。

多组注意清空。

树结构注意单边和双边。

STL

STL 常用算法_golitter.的博客-CSDN博客

熟悉stl的数据结构,string, map, set,queue, stack, priority_queue, vector,array等。

熟悉stl的算法函数

cpp 复制代码
lower_bound()
upper_bound()

find()
count()
substr()
*max_element()
sort()
unique()

在c++11中,max和min函数可以多个值。

cpp 复制代码
max({v1,v2,v3,v4})

优先队列的重载

cpp 复制代码
// 用priority_queue 自定义堆 http://www.cbww.cn/news/37826.shtml
//      要重载 < 操作符 ,注意两个const才可以通过编译
// 方法一 重载运算符<
struct adt { // 小顶堆
    int a;
    bool operator<(const adt& rhs) const { // 优先队列的><与sort的><相反. ** 没有const会报错
        return a > rhs.a; // 这里 从大到小进行排序,队列从最右边开始,所以是小顶堆
    }
};
// 方法二 使用lambda表达式
void test_priority_queue() {
    auto cmp = [](int pre, int suf) { return pre > suf; }; // 小顶堆
    priority_queue<int,vector<int>, decltype(cmp)> pq(cmp); // decltype 类型说明符

    // 实现自定义PII堆结构
    auto pii_cmp = [](PII pre, PII suf) {return pre.vf < suf.vf; };
    priority_queue<PII, vector<PII>, decltype(pii_cmp)> heap(pii_cmp);

}

<bitset> * 是由int型拼接的, e.g. 1000位bitset 操作时间复杂度 O( 1000 / (大于等于 32))

熟悉运用pair<int,int>vector

vector重新赋值

cpp 复制代码
vector<int> ve;
ve.assign(N,3)

整数取整,可以用(LL)(ceil(a / b)),也可以用a / b + (a % b == 0 ? 0 : 1)

lambda表达式的使用:

  • 自定义排序
cpp 复制代码
sort(all(ve), [](int pre, int suf) {
	return pre > suf; // 从大到小
});
// 等价于
sort(all(ve), greater<int>());
  • 写函数
cpp 复制代码
auto lam = [&](int a) -> int {
	if(a > 0) return 1;
	else if(a == 0) return 0;
	else return -1;
}

注意lambde递归用法,c++11可以用

cpp 复制代码
functional<void(int)> dfs = (int u) {};

c++14可以用

cpp 复制代码
auto dfs = [&](auto &&dfs, int u) -> void {};

创建数组,个人常用vector

cpp 复制代码
vector<vector<int>> f(n, vector<int> (n, 1));

算法代码实现

个人算法模板整理:2022/Algorithm__Template at main · golitter/2022 (github.com)

不定项输入

cpp 复制代码
// 需要包含 <sstream>
stringstream put_str;
string str;
getline(cin, str);
put_str<<str;
int cnt = 0,p;
while(put_str>>p) cnt++;

二分答案

  • 最大值最小
cpp 复制代码
int l, r;
while(l < r) {
	int mid = l + r >> 1;
	if(check(mid)) r = mid;
	else l = mid + 1;
}
  • 最小值最大
cpp 复制代码
int l, r;
while(l < r) {
	int mid = l + r + 1 >> 1;
	if(check(mid)) l = mid;
	else r = mid - 1;
}

去重离散化

cpp 复制代码
vector<int> a,id,last;
id = a;
sort(id.begin(), id.end());
id.erase(unique(id.begin(), id.end()), id.end()); // 去重
for(int i = 0; i < n; ++i) {
	last[i] = lower_bound(id.begin(), id.end(), a[i]) - id.begin();
}

建图

  • 链式前向星
cpp 复制代码
// 链式前向星
int h[N]; // 链表头,初始为-1 memset(h, -1, sizeof(h));
int e[N]; // 链表内容
int ne[N]; // 链表中指向下一个元素的指针
int w[N]; // 链表内容的权重
bool vis[N];
int idx; // 
// <u   , -- c -- , v>  ( u --- w --> v
void add(int u, int v, int c) {
    e[idx] = v, w[idx] = c, ne[idx] = h[u], h[u] = idx++;
}
  • vector<pair<int,int>> 或者 vector<array<int,2>>
cpp 复制代码
vector<vector<int>> g(n + 1); // 无权重w
vector<vector<pair<int,int>>> g(n + 1); // 有权重

时间复杂度

1e8大概1秒。

注意调和级数等反直觉时间复杂度。

注意根据给的数据范围和特殊性猜解法。

刷题策略

30分钟没有思路就可以看题解了,不能没有思路就看题解。

刷题 + 写题解 提高较快,便于复习(虽然不复习

每次模拟赛要有总结和反馈。

平时要注意找到自己模拟赛时的不好的状态和好的状态,进行加强或减少。比如,我就是做题,想出来一点就去敲代码,之后再想剩下的算法。其实这是很不对的,算法竞赛主要考察的算法而不是什么代码,目前也在一直减少这个状况发生。

就算自己AC了题,也不要忘了去看看大佬们的代码,可能他们更加简洁,可以学学不同的思路等。

相关推荐
怀旧,3 分钟前
【C++】1. C++基础知识
开发语言·c++·算法
Gerry_Liang18 分钟前
LeetCode热题100——155. 最小栈
算法·leetcode·职场和发展
TechCampus33 分钟前
小红书面试中我这样解释 KMP,面试官点头了
算法
Youndry35 分钟前
验证二叉搜索树
算法
Spider_Man37 分钟前
从 "字符拼图" 到 "文字魔术":动态规划玩转字符串变形术
javascript·算法·leetcode
玄妙尽在颠倒间1 小时前
雪花算法:从 64 位到 128 位 —— 超大规模分布式 ID 生成器的设计与实现
后端·算法
Star在努力1 小时前
15-C语言:第15~16天笔记
c语言·笔记·算法
CoovallyAIHub1 小时前
工业质检新突破!YOLO-pdd多尺度PCB缺陷检测算法实现99%高精度
深度学习·算法·计算机视觉
gb42152871 小时前
负载均衡算法中的加权随机算法
windows·算法·负载均衡
xdlka2 小时前
C++初学者4——标准数据类型
开发语言·c++·算法