对于输入输出的思考

对于输入输出的思考

对于大部分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;
}
posted @ 2020-03-25 12:36  et3_tsy  阅读(130)  评论(0编辑  收藏  举报