对于输入数据非常大的一些变态题目,输入占据大量时间的题目。scanf就会大大拖慢程序的运行速度,cin就更不用说了,所以我们要用一种高大上的东西—— 读入优化。
读入优化的原理其实就是一个一个字符的读入,再组成数字
int read()
{
int x=0,f=1;
char ch;
while(ch<'0'||ch>'9') {if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return f*x;
}
这就是最基本的读入优化,通过getchar函数依次读入字符,用x记录答案,用f判断正负。在主程序中调用时int n=read();即可。
基于类模板的读入优化
template<class T>void read(T &x)
{
x=0;int f=0;char ch=getchar();
while(ch<'0'||ch>'9') {f|=(ch=='-');ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
x=f?-x:x;
return;
}
template就是让这个函数随时可以调用,而且可以用int、double、char……
下面的f |= (ch==’-’) 如果ch==‘-’,f就改符号(还可以判断多个负号),位运算,会快;2<<x就相当于2x,会非常快。
总之就是一个很快的读入优化,真的比普通的读入优化要快很多。
调用时直接read(n)就好了,使用指针的。
基于文件流的读入优化
但只能freopen条件下使用(其实用的不是很多,大多数情况用上面那种)
下面是比以上读优都要快的julao的读入优化(划重点)fread
inline char GET_CHAR(){
static char buf[maxn],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,maxn,stdin),p1==p2)?EOF:*p1++;
}
template<class T>void read(T &x)
{
x=0;int f=0;char ch=GET_CHAR();
while(ch<'0'||ch>'9') {f|=(ch=='-');ch=GET_CHAR();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=GET_CHAR();}
x=f?-x:x;
return;
}
简单的来说就是把getchar函数手写,改为文件读入(fread)。
fread原理:把数据流整段的存到数组buf中,整段的读取,数组存满了再重新覆盖。所以比getchar()一个一个读要快。