P10815 题解

· · 题解

一般的快读移步其他题解,这里说下快读的优化。

首先,就做题而言,一般不会出现输入已经结束仍然尝试输入的情况,因此对读入字符的优化中的判断读完并返回 EOF 的判断是多余的。

其次,赋值语句是有返回值的,所以以下代码:

char c=getchar();
while(c<'0'||c>'9')c=getchar();

实际上等价于:

char c;
while((c=getchar())<'0'||c>'9');

(第二份代码似乎有点 UB,接下来的优化会解决这个问题。)

其次,如果输入内容只包括数字(和空白字符,如空格,\n,\r 等),那么实际上我们可以去掉判断数字时对上界的检查:

char c;
while((c=getchar())<'0');

这是基于以上原理的不能读负数的快读。

inline void read(int &x){
    char c;
    while((c=getchar())<'0');
    x=c^'0';
    while((c=getchar())>='0')x=x*10+(c^'0');
}

这是 getchar:

char gtc(){
    static char tmp[100000],*p=0,*top=0;
    if(p==top)top=(p=tmp)+fread(tmp,1,100000,stdin);
    return *p++;
}

AC 代码:

#include<iostream>
#include<cstdio>
using namespace std;
char tmp[100000],*p(0),*top(0);
#define gtc() (p==top && (top=(p=tmp)+fread(tmp,1,100000,stdin)),*p++)
int read(){
    int x;
    char c;
    bool f=0;
    while((c=gtc())<'0')if(c=='-'){f=1;}
    x=c^'0';
    while((c=gtc())>='0')x=x*10+(c^'0');
    return f?(~x+1):x;
}
int main(){
    int n,x,ans=0;
    n=read();
    while(n--){
        ans+=read();
    }
    cout<<ans;
    return 0;
}

最慢的点跑了 1.33s 速度勉强还是可以的(叠甲.jpg)。