21/3/8
今天做一道比较水的题,用手写快排竟然还TLE?!
气不过,又调用了STL的快排,依然TLE。。。我TM。。。
然后看了一下题解,结果发现了C++一个致命弱点,cin cout太慢了555 。。。
为什么呢,因为cin cout读写还要经过缓存区还有其他什么乱七八糟的原因反正就是很慢,比scanf printf还要慢(毕竟scanf和printf是要指定数据类型进行读写的,cin和cout自己判断数据类型可能有点累吧)
所以,今天不谈算法,就谈一下让程序变快的快读和快写!
快读代码比较简单,先上代码:
inline int read() {int s = 0, w = 1;//这里s存数据的绝对值,w存正负号char ch = getchar();//据说getchar比cin快了不止一丢丢while (ch < '0' || ch>'9') { if (ch == '-')w = -1; ch = getchar(); }while (ch >= '0' && ch <= '9') s = s * 10 + ch - '0';return s * w;
}
是不是很简单?如果想精益求精再快一点的话,可以把数值调用改成位运算,这样每次读入都会快一点,如果数据规模很大的话整体速度也会得到可观的提升:
inline int read() {int s = 0, w = 1;char ch = getchar();while (ch < '0' || ch>'9') { if (ch == '-')w = -1; ch = getchar(); }while (ch >= '0' && ch <= '9') s = s * (1 << 1) + s * (1 << 3) + ch - (1 << 4) - (1 << 5);//这里(1<<1)+(1<<3)是10,(1<<4)+(1<<5)是48,也是'0'的ASCII码return s * w;
}
至于函数名前面的inline,就是类似于宏定义的函数声明,可以比常规函数声明快一点。
还有快写,虽然没遇到过,但是还是搬运一下以备不时之需
inline void write(int x)
{char ch[20];int len=0;//ch里面存的是从低到高的数字的ASCLL码 len是数组长度 if(x<0)//如果x是负数,那么先输出负号,再把x变成正数 {putchar((1<<5)+(1<<3)+(1<<2)+1);//(1<<5)+(1<<3)+(1<<2)+1就是'-'的ASCLL码值 x=~x+1;//x=~x+1;就等同于x=-x;}do//用do while可以防止x=0的特殊情况 {ch[len++]=x%10+(1<<4)+(1<<5);//取出最低位存到ch数组里面 因为ch是字符数组,所以要加上0的ASCLL码 x/=10;//砍掉最低位 }while(x>0);//当x>0的时候每次把x的最低位取出 for(int i=len-1;i>=0;i--)//因为ch是从低到高存的x的绝对值,又因为要从高到低输出,所以倒着循环ch数组输出 putchar(ch[i]);//输出从高到低的每一位 return ;
}
如代码,快写就是将一个整型快速输出,当然也可以吧int改成longlong,看题目具体需要吧
以上是算法性的东西,其实也可以采用关同步的方式加快cin,cout的速度(但没有快读快写快),只需要在main函数开头写一句std::ios::sync_with_stdio(false)
就好了。但是关同步后读取某些数据类型可能会发生玄学错误,如果发现不对就不要用了。