ACM比赛常用代码,函数,头文件。有哪些?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ACM比赛常用代码,函数,头文件。有哪些?相关的知识,希望对你有一定的参考价值。

常用的头文件如下

#include<assert.h>//设定插入点

#include<ctype.h>//字符处理

#include<errno.h>//定义错误码

#include<float.h>//浮点数处理

#include<fstream.h>//文件输入/输出

#include<iomanip.h>//参数化输入/输出

#include<iostream.h>//数据流输入/输出

#include<limits.h>//定义各种数据类型最值常量

#include<locale.h>//定义本地化函数

#include<math.h>//定义数学函数

#include<stdio.h>//定义输入/输出函数

#include<stdlib.h>//定义杂项函数及内存分配函数

#include<string.h>//字符串处理

#include<strstrea.h>//基于数组的输入/输出

#include<time.h>//定义关于时间的函数

#include<wchar.h>//宽字符处理及输入/输出

#include<wctype.h>//宽字符分类标准C/C++(同上的不再注释)#include<algorithm>//STL通用算法

#include<bitset>//STL位集容器

#include<cctype>

#include<cerrno>

#include<clocale>

#include<cmath>

#include<complex>//复数类

#include<cstdio>

#include<cstdlib>

#include<cstring>

#include<ctime>

#include<deque>//STL双端队列容器

#include<exception>//异常处理类

#include<fstream>

#include<functional>//STL定义运算函数(代替运算符)

#include<limits>

#include<list>//STL线性列表容器

#include<map>//STL映射容器

#include<iomanip>

#include<ios>//基本输入/输出支持

#include<iosfwd>//输入/输出系统使用的前置声明

#include<iostream>

#include<istream>//基本输入流

#include<ostream>//基本输出流

#include<queue>//STL队列容器

#include<set>//STL集合容器

#include<sstream>//基于字符串的流

#include<stack>//STL堆栈容器

#include<stdexcept>//标准异常类

#include<streambuf>//底层输入/输出支持

#include<string>//字符串类

#include<utility>//STL通用模板类

#include<vector>//STL动态数组容器

#include<cwchar>

#include<cwctype>usingnamespacestd;//////////////////////////////////////////////////////////////////////////C99增加#include<complex.h>//复数处理

#include<fenv.h>//浮点环境

#include<inttypes.h>//整数格式转换

#include<stdbool.h>//布尔环境

#include<stdint.h>//整型环境

#include<tgmath.h>//通用类型数学宏
参考技术A #include<iostream>
#include<memory.h>
#include<cstdio>
#include<cmath>
#include<queue>
#include<algorithm>
#include<stack>
#include<cstring>
#include<vector>
#include<list>
#include<set>
参考技术B #include<time.h>
#include<iostream>
#include<ctype.h>
#include<map>
#include<set>
#include<algorithm>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<vector>

一个合格的ACMer的代码当中,都藏着哪些秘密?

作者 | 梁唐       责编 | 欧阳姝黎

今天给大家聊聊C++中的头文件,之前我在写算法专题展示源代码的时候,很多小伙伴给我留言说被我的头文件中的内容震惊了。其实之所以我的头文件这么复杂,完全是因为它是我一直从大学时期acm竞赛当中沿用下来的。对于acm竞赛的选手们来说,这样的头文件其实算是小儿科了。

今天就和大家来看看,acmer 的头文件当中都藏着哪些秘密。

首先,我们先来看我完整的头文件代码。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <functional>
#define rep(i,a,b) for (int i=a;i<b;i++)
#define Rep(i,a,b) for (int i=a;i>b;i--)
#define foreach(e,x) for (__typeof(x.begin()) e=x.begin();e!=x.end();e++)
#define mid ((l+r)>>1)
#define lson (k<<1)
#define rson (k<<1|1)
#define MEM(a,x) memset(a,x,sizeof a)
#define pii pair<int, int>
#define LL long long
using namespace std;
const int N=500005;
const long long Mod=99997867;

include部分

首先我们来看 include 的部分,我们一个一个来看,iostream 不用多说了,C++标准输入输出的头文件,包含了 C++输入输出流函数,也就是经典的 cin、cout。说到 cin、cout 多说两句,cin、cout 的开销要比 C 语言下的 scanf 和 printf 慢很多,很容易影响程序运行的性能。所以对于 acmer 来说,能用 scanf 和 printf 完成的,就绝对不会用 cin、cout。当然 scanf 和 printf 也不是最快的,还有更快的 getchar 和 putchar,所以有些玩家会自己手写循环读入 char 然后转成 int 或者是 float 的函数,当然绝大多数情况下并不需要这样。

cstdio 和 iostream 同样的功能,不过是 C 语言中的输入输出函数,不多说。

cstring 同样属于 C 语言,是 C 语言中的字符串库,有很多字符串相关的函数。同样由于性能的原因,能用 C 语言中 char[]完成的就不用使用 C++的 string。接下来的 string 库也不用多说,C++的字符串处理库。

cstdlib 库函数等同于 C 语言中 stdlib.h,封装了一些常用的库函数,如 rand、srand、free、malloc 等。

cmath 库等于 C 语言中的 math.h,封装了一些数学运算相关的库函数,如 pow、sqrt 等。

后面的 queue、vector、map、set 都是 STL 库,包含了一些比较好用的数据结构。比如 queue 中封装了 queue 以及 dequeue,和 priority_queue,也就是队列、双端队列和优先队列。vector、map、set 分别是线性表、映射表以及集合,熟练使用它们可以极大的降低编码的复杂度。

algorithm 库翻译过来就是算法库,当中自然封装了不少的算法。比如 sort 排序、reverse 翻转、next_permutation 下一个全排列、lower_bound、upper_bound 函数等。

最后一个 functional 库,用得不多,顾名思义当中封装了一些关于函数对象的操作。比如 bind、reference_wrapper 等等。

其实关于 include,有一个取巧的方法可以一次性 include 所有的头文件:

#include <bits/stdc++.h>

不过这种方法有一个小问题,并不是所有的环境都支持,尤其是在正式比赛的场合,所以一般情况下大家都是一些网络赛才会用它,我个人由于懒得区分环境,所以还是习惯自己一个一个 include。

define部分

define 是 C++ 当中非常强大的功能,它可以定义规则对代码进行替换。熟练使用 define 同样可以大大简化编码。但是要注意,凡事不能过度,如果 define 使用过多会影响程序的可读性,也可能对其他人的编码造成影响。所以很多大公司是禁止使用 define 的,我个人倒觉得其实也不用这么严肃,define 可以用,遵守规范,适当使用就可以了。

首先是这两行,是 for-loop 的 define。

#define rep(i,a,b) for (int i=a;i<b;i++)
#define Rep(i,a,b) for (int i=a;i>b;i--)
#define foreach(e,x) for (__typeof(x.begin()) e=x.begin();e!=x.end();e++)

rep 是 repeat 的缩写,使用的时候只需要 rep(i, a, b)就可以代替冗长的 for 循环的编写,其中 i 是循环变量,a 和 b 分别是循环的上下界,注意是左闭右开区间。

Rep 也是同样的逻辑,只不过是倒序的循环。

foreach 使用的是 C++11 的新特性,可以实现自动迭代,用的不多,在一些场景下非常方便。

#define mid ((l+r)>>1)

这行用在二分查找当中,左边界是 l,右边界是 r,那么它们的中点就是(l + r) / 2,用位运算表示就是:(l + r) >> 1。例子:

# define之前
while (l + 1 < r) {
    int m = (l + r) >> 1;
    if (a[m] <= v) {
  l = m;
    }else {
  r = m;
    }
}

# define之后
while (l + 1 < r) {
    if (a[mid] <= v) {
  l = mid;
    }else {
  r = mid;
    }
}

#define lson (k<<1)
#define rson (k<<1|1)

这两行主要是用在线段树上,因为 C++ 往往不使用类来实现线段树,而是通过数组来模拟实现。在线段树当中,如果某一个节点的 id 是 u,那么它的左孩子是 2 x u,右孩子的 id 是 2 x u + 1,用位运算来表示就是 u << 1 和 u << 1 | 1。

#define MEM(a,x) memset(a,x,sizeof a)
#define pii pair<int, int>
#define LL long long 

最后三行放在一起说,第一行是 memset 的缩写,memset 可以用来初始化数组。pii 缩写了 pair<int, int>,pair 是用来绑定两个变量的数据结构。最后是 LL 缩写了 long long,long long 是 64 位的 int,它的范围要比 int 大得多。

关于类型的重定义,这里使用 define 并不是非常好,更好的方法是使用 typedef,例如上面的 pair 和 long long 可以写成:

typedef pair<int, int> pii;
typedef long long LL;

相比 define 之下这样更规范一些,因为 define 是生硬的字符串替换,而 typedef 则是类型别名,能够被编译器检查,所以能使用 typedef 还是使用 typedef。

尾声

除了上面用到的这些头文件之外,还有一些更高端的用法,比如一些模板类,以及一些常用的算法,比如 gcd 等等。但我个人觉得意义不是非常大,对于面试、笔试的代码环节来说,以上的这些头文件已经足够使用了。



☞苹果iCloud(贵安)数据中心投入运行;网易公布不当言论HR处理结果:已开除;OceanBase数据库将开源|极客头条☞程序员35岁就该退休了吗?☞从“不作恶”到“门就在那边”,谷歌 AI 伦理史

以上是关于ACM比赛常用代码,函数,头文件。有哪些?的主要内容,如果未能解决你的问题,请参考以下文章

ACM竞赛常用头文件模板

ACM比赛一个学校能派几个队?

2019省赛ACM总结

比较好的大学生C语言竞赛编程题 或者比较有档次的竞赛都有哪些(本科、研究生可以参加的) ?

一个合格的ACMer的代码当中,都藏着哪些秘密?

ACM-ICPC 比赛环境的使用