有关算法竞赛的一些小技巧和小建议

本文介绍了C++编程的一些实用技巧,如头文件的使用,包括全包含头文件和单独引入,以及它们的优缺点。强调了命名空间、C++11特性、输入输出效率优化和防止整数溢出的方法。还分享了针对不同数据规模应选用的算法复杂度,为编程竞赛提供了策略指导。

首先关于头文件的使用,个人比较喜欢用这种

#include<iostream>
#include<algorithm>
#include<cstring>

这种头文件的优点 : 编译快,在你debug的时候会很爽,一秒钟就编译好了,
缺点: 需要加很多头文件,有时候你用一些函数时,忘记了它的头文件就会非常头痛,所以平时刷题时要有意识的去记一下他们的头文件,敲多了就记住了

另一种

#include<bits/stdc++.h>

相信这种头文件大家应该见的很多, 懒人必备头文件,
优点: 包括了大量的头文件,减少了敲头文件的时间
缺点: 编译时间巨长! 当你频繁的debug的时候,心态容易爆炸

然后有一些同学,只学了C语言的同学,可能不太懂C++的语法,我在这里简单介绍一下, 在竞赛方面C++和C的区别最大就是输入输出不同,还有一点就是多了一个强大的工具,STL,这是一个非常牛的库

在C++的开头通常会加上这么一句话

using namespace std;

可不可以不加呢? 当然可以

优点: 有时候我们常常在定义变量时,编译器会给我们报错,之所以会报错,是因为我们的变量名和某些库函数的变量名冲突了,但是我们如果不加using namespace std; 这句话,就不会导致冲突, 但是带来的麻烦就是
你的代码得这样写

#include<bits/stdc++.h>
std::vector<int>a;
int main()
{
     int n, x;
     std :: cin >> n;
     for(int i = 1; i <= n; i ++ )
     std :: cin >> x, a.push_back(x);

     for(auto x : a)
     std :: cout << x << " "; 
}

using namespace std; 的意思就是开辟新的命名空间,如果你没有开辟这个空间,那么你就得每次都通过 stdstdstd 访问这些库函数
好了看了上面的代码,你又疑惑了, for(auto x : a) 又是啥啊, 这也正是我要告诉你们的, C++11 的一个特性,可以通过元素 xxx 访问容器 aaa 里面的每个元素,而 autoautoauto xxx 的意思就是 我容器里面存放的元素是什么类型,我的 xxx 就是什么类型,比如 aaa 是一个结构体类型的 vectorvectorvector, 那么 xxx 就是一个结构体

然后我们在写题,打比赛时,经常会出一个问题,那就是爆int,这个错误经常出现,然后我就比较喜欢加上这么一句话,来防止爆int

#define int long long 

这句话是什么意思? 把所有的 intintint 都看作 longlonglong longlonglong, 这样是不是就能防止爆int了,但是随之而来的问题就是 我的主函数是不能为 longlonglong longlonglong 类型的,所以我们的主函数应该这样

signed main()

然后我们要记得如果使用 scanfscanfscanfprintfprintfprintf 时,要记得把变量对应的类型写成 %lld

其次,如果你用 cincincin, coutcoutcout 来输入和输出时,会比 scanfscanfscanf, printfprintfprintf 慢一点,输入规模在一百万以内两个是没有区别的,但是超过一百万推荐使用 scanfscanfscanf, printfprintfprintf,虽说有些人会使用一些黑科技,

ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);

这个的作用就是关闭同步,从而提高 cincincin, coutcoutcout 的效率,
然后最重要的一点!!!
coutcoutcout 换行,不要用

cout << endl;

endl会使得你的程序变慢很多,一定不要用!!
要换行就用

cout << "\n"; 

然后就是根据数据范围反推算法
引用 -> y总

一般 ACMACMACM 或者笔试题的时间限制是 111 秒或222 秒。
在这种情况下,C++代码中的操作次数控制在 10710^710710810^8108为最佳。
最好控制在 10710^7107,除非你是常数计算大师(补充,在C++的每次计算中会产生常数,常数越大,会导致运行时间越长,stlstlstl的容器会比手写的容器的常数要大一点,在一般情况下, stlstlstl是不会超时的的
下面给出在不同数据范围下,代码的时间复杂度和算法该如何选择:

n≤30n≤30n30, 指数级别, dfs+剪枝,状态压缩dp

n≤100n≤100n100 => O(n3n^3n3),floyd,dp,高斯消元

n≤1000n≤1000n1000 => O(n2n^2n2),O(n2lognn^2 lognn2logn),dp,二分,朴素版Dijkstra、朴素版Prim、Bellman-Ford

n≤10000n≤10000n10000=> O(nnn × n\sqrt{n}n),块状链表、分块、莫队

n≤100000n≤100000n100000=> O(nlognnlognnlogn)=> 各种sort,线段树、树状数组、set/map、heap、拓扑排序、dijkstra+heap、prim+heap、Kruskal、spfa、求凸包、求半平面交、二分、CDQ分治、整体二分、后缀数组、树链剖分、动态树

n≤1000000n≤1000000n1000000=> O(nnn), 以及常数较小的 O(nlognnlognnlogn) 算法 => 单调队列、 hash、双指针扫描、并查集,kmp、AC自动机,常数比较小的 O(nlogn)的做法:sort、树状数组、heap、dijkstra、spfa

n≤10000000n≤10000000n10000000=> O(nnn),双指针扫描、kmp、AC自动机、线性筛素数

n≤109n≤10^9n109=> O(n\sqrt{n}n),判断质数

n≤1018n≤10^{18}n1018=> O(logn),最大公约数,快速幂,数位DP

n≤101000n≤10^{1000}n101000=> O((lognlognlogn) × 2),高精度加减乘除

n≤10100000n≤10^{100000}n10100000=> O(logklogklogk × log(logk)log(logk)log(logk)),kkk 表示位数,高精度加减、FFT/NTT

我能说的就这么多了,这是我的全部经验,

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

广西小蒟蒻

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值