不定期更新

1.cin\cout太慢导致超时

找了很久,发现如果因为输入输出太慢导致超时,最好两个命令一起用。
ios::sync_with_stdio(false);
cin.tie(0); //0表示NULL

这里额外说一下原理。我们一般情况下可以混用cin和scanf是因为cin与scanf保持了流同步。
C++为了兼容C,保证程序在使用了std::printf和std::cout的时候不发生混乱,将输出流绑到了一起。
而也因此,cin变得缓慢,第一行代码便解除了流同步,从而提高cin效率。但是,这样做以后,
因为流不同步了,不能再混用c++和c的输入输出语句了。这个函数是一个“是否兼容stdio”的开关。

在默认的情况下,cin绑定的是cout,每次执行 << 流操作符的时候都要调用flush,这样会增加IO负担。
第二行的代码用来解除cin与cout的绑定,进一步加快执行效率。

即便如此,cin效率应该还是不及scanf,差不太多但是还是慢一点。(这句话是个人感觉)

2.变量定义位置的问题

开始acm道路之后,我习惯了把很多变量放到全局变量,省去函数之间引用传递的麻烦,

需要初始化的时候用memset。这个做法方便但其实有不安全的地方,那便是递归函数。
因为在递归函数中,某个变量在某次递归中都有一个值,可是如果将它声明为全局变量,
那该变量就不随着递归函数而改变。举个常见的例子,在dfs中for循环的回退,
如果意外(新人可能会这样做)将变量声明在for之外,就有可能有问题。
所以可能同样的代码,函数内使用局部变量的代码A了,而全局变量的WA了。
这个案例告诉我们,有时候wa了不是算法问题,只是因为一个变量的位置。

3.声明优先队列的时候

priority_queue默认为大顶堆,若要声明为小顶堆,需要
priority_queue<int,vector<int>,greater<int> > ipq;

此时“greater<int>”与 “>”中间要有一个空格,否则编译器会将两个'>'理解为流操作符。
额外说一句,如果不是int类型而是自定义类型,需要重载小于符号。sort()函数重载也是重载小于号。


4.在结构体、类中需要储存字符串的时候,可能导致的内存溢出错误(RE)

我们知道,可以用 string=char[]来初始化字符串。于是有次做字典树,用节点储存一个字符串,我在节点中声明了

个string变量,在insert的时候先new node(),然后直接让string=char[]导致RE。这是因为new的时候不知道

string占用的空间大小所以没分配(推断,应该是),解决方法,不要在node结构体/类中声明string,

而声明char* val; 在需要赋值的时候,使用以下代码来将字符串储存到节点中。

p->val = (char*)malloc((strlen(v)+1)*sizeof(char));//p是指向node的指针,v是待储存的字符串  
strcpy(p->val,v);//将要存的字符串v存入p所指的结构体/类中的char*指针val所指的地址。

5.不要申请动态数组,直接全局变量,然后用memset重置就好了。memset因为底层的cache优化所以特别快

在比赛中,遇到动态数组问题一般不用申请动态数组。
比如用深、广搜的时候储存邻接矩阵,开个全局变量的大数组,然后每次都利用memset清0。

用法是memset(数组名称,0/-1,sizeof(数组))
第二个参数填0代表将数组清0(填-1则将数组全部变成-1),
需要注意的是,填1等其他值不会将数组以1填充。
如果你想要将一个数组全部填成某个特定的数,请用fill函数


6.大量增删时应用list而非vector

7.c++读取一整行的方法汇总

string s;
getline(cin,s);
cout<<s<<endl;


char s[100];
scanf("%[^\n]%*c",s);
printf("%s\n",s);


char s[100];
gets(s);
printf("%s\n",s);


char s[100];
cin.get(s,100);
printf("%s\n",s)


char s[100];
cin.getline(s,100);
printf("%s\n",s);

getline(cin, line)
stringstream ss(line);
while(ss >> a){
  cout << a<< endl;
}  

8.使用系统函数进制转换

进制数任意给定,甚至还有100进制呢。。。
       char *s;    
    s=new char;
    int v=0x7fffffff;
    char *b;
    b=itoa(v, s, 16);
    printf("%s",b);
这段代码输出的是整数最大值的16进制,所以输出7fffffff

9.灵活使用auto变量

c++新的auto是类型推断,以前的auto是自动变量。现在,可以用auto来写代码了!
不需要再写什么iterator了!
map<string,int> m;
m["hello"]=1;
m["world"]=2;
for(auto i=m.begin();i!=m.end();i++){
    cout<<i->first<<i->second<<endl;
}