刚刚ldw老师给我恶补了一些奇奇怪怪的东西,总结一下
1.MLE=memory limit exceeded
空间内存太大啦,数组开过头了。
一般开在1e7左右就要计算一下了,怎么算呢?
int 4字节 1 KB=1e3 B
bool 、char 1字节 1 MB=1e6 B
....... 1 G=1e9 B
所以1e7大概就是10MB,一般题目要求都在256MB。但如果开到1e8,并且是int的话,扳扳手指算一算,400MB,死定啊!
2.用STL中的vector来搞邻接表
(还可以用前向星来存储,就是什么first,next,to什么之类的)
首先,vector是一个动态数组(如果遇到1的问题,数组开太大,就可以想想动态数组了,但听说vector效率有点低,不过没什么关系,一般没人卡这个)
#include<vector>//头文件
vector<int> q;//数据类型也可以是自己定义的
q.push_back(2)//比如放个2进去,则q[0]=2;
int s=q.size()//s里存了现在q的大小,比如现在就是1
上面是蒟蒻认为最基础的
下面是大总结的
v.size() :返回v的元素个数
v[i]:返回索引i所标识的元素,和数组用法几乎完全相同。对i不进行越界检查。
v.push_back(e):在尾部添加一个元素e的副本。
v.pop_back():移除最后一个元素但不返回最后一个元素。
v.erase(begin, end):删除区间$[begin, end)$内所有元素,返回下一个元素的位置。
v.clear():移除所有元素,清空容器。
注意,erase操作涉及大量元素的移动,可能会严重影响效率。
3.if(~i)等价于if(i!=-1),但会快一些
~在位运算中的意思就是取反,-1的二进制表示是1111111111(一连串的1),取反就是0000000000,所以当i=-1时if语句不成立
还有:i!=n比i<=n快
4.&和*
&是取地址符,*相当于取该地址上的值
int * p; //此时的p就相当于一个指针变量,用来存储地址的
p=&a; //就是把a的地址位置给p
如果 printf("%d",p) 输出的就是a的地址
但如果写成 printf(“%d",*p) 就是输出a的值
&也是引用的符号
int &a=b; //表示a,b是一个东西,a变b也变,b变a也变(a相当于b的外号)
平时我们的输入scanf("%d",&a[i])
其实也可以写成scanf("%d",a+i) 至于为什么要这么写,主要是看个人心情,不想打&这个东西,就可以这样写
甚至输出也可以变成printf("%d",*(a+i));
5.取字符串的长度不一定要用strlen(ch),可以有比它快的
比如说
for(i=1;ch[i]!='\0';++i){
做你想做的事;
}
为什么可以这样处理呢?因为字符串的结尾都是以'\0'结束的
6.补充一点关于vector的
如果你是这样的:vector<node> q[N]; //node是自己定义的数据结构
那么怎么添加数据呢
struct node{
int v,w;
node(int _v=0,int _w=0){//注意这个地方要有初值
v=_v;w=_w;
} //先弄一个构造函数
};
node t;
vector<node>g[N];
for(int i=1;i<=m;i++){
int u,v,w;
cin>>u>>v>>w;
g[u].push_back(node(v,w));//然后添加就好了
}
但如果你不喜欢构造函数,也可以强行转
g[u].push_back( (node) {v,w} );