Loading [MathJax]/extensions/tex2jax.js
NOIP学习小站
西安交通大学附属中学航天学校

快读

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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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();
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();
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();
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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);
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);
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);

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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
s = (s<<3)+(s<<1)+ch-'0'; //s<<3 s左移三位相等于 s*8;s<<1 s左移一位相等于 s*2,移位运算效率更高
s = (s<<3)+(s<<1)+ch-'0'; //s<<3 s左移三位相等于 s*8;s<<1 s左移一位相等于 s*2,移位运算效率更高
s = (s<<3)+(s<<1)+ch-'0';   //s<<3 s左移三位相等于 s*8;s<<1 s左移一位相等于 s*2,移位运算效率更高

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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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();
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();
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();
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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);
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);
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\))进制的非负整数(读入后转成十进制数),函数可以这样设计:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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);
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);
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);
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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);
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);
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组数据,每组数据一行包括三个用一个空格隔开的非负整数,计算并输出每组整数的和。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#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> 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> 
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;
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#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;
}
#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; }
#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;
}

登录

注册