NOIP学习小站
西安交通大学附属中学航天学校

快读

遇到要输入处理较多整数的题目时,用scanf或者cin肯定是不够快的。由于getchar()有速度快的特性,所以可以使用getchar()整数按照单个字符的方式输入并重新组装,对比scanf,这样做效率可以提高数倍。可以将以“getchar()读入整数每一位并组装”的过程写成一个函数以方便调用。

int read(){
	//f记录符号 
	int s = 0, f = 1;
	char ch = getchar();
	//读入符号(过滤了非数字字符) 
	while (ch < '0' || ch > '9'){
		if (ch == '-') f = -1;
		ch = getchar();
	}
	//读数字字符并组装整数 
	while (ch >= '0' && ch <= '9'){
		s = s * 10 + ch - '0';
		ch = getchar();
	}
	return s * f;
}
//调用方法
// int num = read();
void read(int &n){
	//f记录符号 
	int s = 0, f = 1;
	char ch = getchar();
	//读入符号(过滤了非数字字符) 
	while (ch < '0' || ch > '9'){
		if (ch == '-') f = -1;
		ch = getchar();
	}
	//读数字字符并组装整数 
	while (ch >= '0' && ch <= '9'){
		s = s * 10 + ch - '0';
		ch = getchar();
	}
	n = s * f;
}
//调用方法
// int num;
// read(num);

其中的组装十进制整数的语句可以借助位运算实现(能提高一些效率):

s = (s<<3)+(s<<1)+ch-'0';   //s<<3 s左移三位相等于 s*8;s<<1 s左移一位相等于 s*2,移位运算效率更高

如果读入的是非负整数,那么函数还可以进一步简化:

int read(){
	int s = 0;
	char ch = getchar();
	//读数字字符并组装整数 
	while (ch >= '0' && ch <= '9'){
		s = (s<<3) + (s<<1) + ch - '0';
		ch = getchar();
	}
	return s;
}
//调用方法
// int num = read();
void read(int &s){
	s = 0;
	char ch = getchar();
	//读数字字符并组装整数 
	while (ch >= '0' && ch <= '9'){
		s = (s<<3) + (s<<1) + ch - '0';
		ch = getchar();
	}
}
//调用方法
// int num;
// read(num);

如果读入的是 \(p\) (\(2 \leq p \leq 16\))进制的非负整数(读入后转成十进制数),函数可以这样设计:

int read(int p){
	int s = 0;
	char ch = getchar();
	//读字符并组装整数 
	while (true){
		if(ch >= '0' && ch <= '9')
			s = s * p + ch - '0';
		else if(ch >= 'a' && ch <= 'f')
			s = s * p + ch - 'a' + 10;
		else if(ch >= 'A' && ch <= 'F')
			s = s * p + ch - 'A' + 10;
		else break;
		ch = getchar();
	}
	return s;
}
//调用方法
// int num = read(16);
void read(int &s,int p){
	s = 0;
	char ch = getchar();
	//读字符并组装整数 
	while (true){
		if(ch >= '0' && ch <= '9')
			s = s * p + ch - '0';
		else if(ch >= 'a' && ch <= 'f')
			s = s * p + ch - 'a' + 10;
		else if(ch >= 'A' && ch <= 'F')
			s = s * p + ch - 'A' + 10;
		else break;
		ch = getchar();
	}
}
//调用方法
// int num;
// read(num,16);

通过一个问题来看快读函数的调用,先输入正整数n,然后输入n组数据,每组数据一行包括三个用一个空格隔开的非负整数,计算并输出每组整数的和。

#include<cstdio> 
int read(){
    int s = 0;
    char ch = getchar();
    //读数字字符并组装整数 
    while (ch >= '0' && ch <= '9'){
        s = (s<<3) + (s<<1) + ch - '0';
        ch = getchar();
    }
    return s;
}
int main()
{
	int n,a,b,c;
	n = read();
	for(int i=1;i<=n;i++){
		a = read();
		b = read();
		c = read();
		printf("%d\n",a+b+c);
	}
	return 0;
}
#include<cstdio> 
void read(int &s){
	s = 0;
	char ch = getchar();
	//读数字字符并组装整数 
	while (ch >= '0' && ch <= '9'){
		s = (s<<3) + (s<<1) + ch - '0';
		ch = getchar();
	}
}
int main()
{
	int n,a,b,c;
	read(n);
	for(int i=1;i<=n;i++){
		read(a);
		read(b);
		read(c);
		printf("%d\n",a+b+c);
	}
	return 0;
}