对于输入输出的思考
对于输入输出的思考
对于大部分oi选手,基本会使用scanf+printf或者cin+cout
两者各有优势
cin,cout有一些流方法很好用,但printf,scanf快,且格式化输出方便
有人使用ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
通过取消绑定同步,来进行时间上优化
确实能与前者相当,甚至在输出上能超过前者
但是,在部分字符串的题目里,你开了取消绑定这一优化后会让你使用cin/cout会TLE,使用scanf/printf就几十ms就过了
就此很多人认为优化了还TLE,哎呀cin/cout真的烂啊
但真的是这样吗?
笔者运行环境是windows10, C++11
为此准备一段10w长字符串,没换行,对,没换行
我把它复制到了我的粘贴版进行实验,第一次取消同步:
它只读了509个字符
第二次,我没有取消同步:
它居然读了4094个
结果笔者实验,scanf最多也是读4094个
现在来分享一下收获:
众所周知,输入输出都是有缓冲区(buffer),它的存在是为了减少打断cpu工作的次数。
一般而言windows环境是以行作为缓冲单位,我们平常敲的回车之所以能够视为输入,实际上它只是换行,再将缓冲区的数据传入,俗称行缓冲,而linux下则不然
(这点同样使得EOF在两个操作系统中有所不同,Windows你必须要在一行开头敲ctrl+z才有用)
缓冲区是有大小的限制,但是取消同步会让它变小(linux我不知道~)
所以会莫名其妙TLE,RE...
当字符与数混合作为输入,也会经常莫名其妙的wa,从而心态爆炸。
所以没必要取消同步,正常读入就好
真正要卡常的话,改用快读还是得把快读掏出来
快读
#include<cstdio>
#define re register
inline int read()
{
re int t=0;
re char v=getchar();
while(v<'0')v=getchar();
while(v>='0')
{
t=(t<<3)+(t<<1)+v-48;
v=getchar();
}
return t;
}