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

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

#include
#include
#include

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

另一种

#include

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

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

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

using namespace std;

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

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

#include
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; 的意思就是开辟新的命名空间,如果你没有开辟这个空间,那么你就得每次都通过 s t d std std 访问这些库函数
好了看了上面的代码,你又疑惑了, for(auto x : a) 又是啥啊, 这也正是我要告诉你们的, C++11 的一个特性,可以通过元素 x x x 访问容器 a a a 里面的每个元素,而 a u t o auto auto x x x 的意思就是 我容器里面存放的元素是什么类型,我的 x x x 就是什么类型,比如 a a a 是一个结构体类型的 v e c t o r vector vector, 那么 x x x 就是一个结构体

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

#define int long long 

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

signed main()

然后我们要记得如果使用 s c a n f scanf scanf p r i n t f printf printf 时,要记得把变量对应的类型写成 %lld

其次,如果你用 c i n cin cin, c o u t cout cout 来输入和输出时,会比 s c a n f scanf scanf, p r i n t f printf printf 慢一点,输入规模在一百万以内两个是没有区别的,但是超过一百万推荐使用 s c a n f scanf scanf, p r i n t f printf printf,虽说有些人会使用一些黑科技,

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

这个的作用就是关闭同步,从而提高 c i n cin cin, c o u t cout cout 的效率,
然后最重要的一点!!!
c o u t cout cout 换行,不要用

cout << endl;

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

cout << "\n"; 

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

一般 A C M ACM ACM 或者笔试题的时间限制是 1 1 1 秒或 2 2 2 秒。
在这种情况下,C++代码中的操作次数控制在 1 0 7 10^7 107 1 0 8 10^8 108为最佳。
最好控制在 1 0 7 10^7 107,除非你是常数计算大师(补充,在C++的每次计算中会产生常数,常数越大,会导致运行时间越长, s t l stl stl的容器会比手写的容器的常数要大一点,在一般情况下, s t l stl stl是不会超时的的
下面给出在不同数据范围下,代码的时间复杂度和算法该如何选择:

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

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

n ≤ 1000 n≤1000 n1000 => O( n 2 n^2 n2),O( n 2 l o g n n^2 logn n2logn),dp,二分,朴素版Dijkstra、朴素版Prim、Bellman-Ford

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

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

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

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

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

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

n ≤ 1 0 1000 n≤10^{1000} n101000=> O(( l o g n logn logn) × 2),高精度加减乘除

n ≤ 1 0 100000 n≤10^{100000} n10100000=> O( l o g k logk logk × l o g ( l o g k ) log(logk) log(logk)), k k k 表示位数,高精度加减、FFT/NTT

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

你可能感兴趣的:(算法,c++,开发语言)