在竞赛中,遇到大数据时,每每须要更快的读取方式。因为比赛中输出通常规模较小,本文只讨论输入如何加速.
如今咱们生成1000000个随机数,构成1000*1000的矩阵,而后输入比较时间(Win 10系统)ios
#include<iostream>
#include<stdlib.h>
#include<ctime>
using namespace std;
int main(){
srand((unsigned)time(NULL));
freopen("out1.txt","w",stdout);
for(int i=1;i<=1000;i++){
for(int j=1;j<=1000;j++){
cout<<rand()<<' ';
}
cout<<endl;
}
}
在比赛中,常常出现数据集超大形成 cin TLE的状况。这时候大部分人(包括原来我也是)认为这是cin的效率不及scanf的错c++
准确的说,cin在不优化的状况下效率是很低的,咱们来测试一下web
#include<iostream>
#include<cstdio>
#include<ctime>
using namespace std;
int a[1005][1005];
int main(){
freopen("out1.txt","r",stdin);
double s=clock();
for(int i=1;i<=1000;i++){
for(int j=1;j<=1000;j++){
cin>>a[i][j];
}
}
printf("time used=%.3fs\n",double(clock()-s)/CLOCKS_PER_SEC);
}
能够看出,cin的用时达到了惊人的0.763s!!!假如运行时间限制为1s,那么程序只剩下0.3秒来计算,是极容易TLE的
所以,遇到大数据时尽可能避免用cin
有博客提到:svg
默认的时候,cin与stdin老是保持同步的,也就是说这两种方法能够混用,而没必要担忧文件指针混乱,同时cout和stdout也同样,二者混用不会输出顺序错乱。正由于这个兼容性的特性,致使cin有许多额外的开销,如何禁用这个特性呢?只需一个语句std::ios::sync_with_stdio(false);,这样就能够取消cin与stdin的同步了函数
其实还有一个等价的写法测试
cin.tie(0);//取消cin的同步
cout.tie(0);//取消cout的同步
咱们来验证一下:大数据
#include<iostream>
#include<cstdio>
#include<ctime>
using namespace std;
int a[1005][1005];
int main(){
freopen("out1.txt","r",stdin);
std::ios::sync_with_stdio(false);//优化
double s=clock();
for(int i=1;i<=1000;i++){
for(int j=1;j<=1000;j++){
cin>>a[i][j];
}
}
printf("time used=%.3fs\n",double(clock()-s)/CLOCKS_PER_SEC);
}
时间变成了0.173s,相比cin是飞跃性的优化
可是别急着高兴,本人亲测,在NOIP的评测机上这样子会爆0
所以,noip比赛中坚定不要写std::ios::sync_with_stdio(false)
爆0的缘由以下
noip明确要求使用freopen,而freopen是stdio库中的,既然咱们已经取消了iostream和stdio的同步,这样会形成文件指针混乱,进而致使RE 优化
既然noip比赛中坚定不要写std::ios::sync_with_stdio(false),那么咱们能够用scanfui
#include<iostream>
#include<cstdio>
#include<ctime>
using namespace std;
int a[1005][1005];
int main(){
freopen("out1.txt","r",stdin);
double s=clock();
for(int i=1;i<=1000;i++){
for(int j=1;j<=1000;j++){
scanf("%d",&a[i][j]);
}
}
printf("time used=%.3fs\n",double(clock()-s)/CLOCKS_PER_SEC);
}
时间变成了0.641s,相比无优化的cin仍是较快的spa
咱们知道,getchar的速度是很快的,但它只能读取单个字符,所以,咱们经过将字符转为整型来优化,同理能够转成long long
快速读入的代码NOIP初赛曾经考过
#include<iostream>
#include<cstdio>
#include<ctime>
using namespace std;
int a[1005][1005];
inline int read(){//很是重要的快速读入代码
int x=0,sign=1;
char c=getchar();
while(c>'9'||c<'0'){//判断符号
if(c=='-') sign=-1;
c=getchar();
}
while(c>='0'&&c<='9'){//转换数
x=x*10+c-'0';
c=getchar();
}
return x*sign;
}
int main(){
freopen("out1.txt","r",stdin);
double s=clock();
for(int i=1;i<=1000;i++){
for(int j=1;j<=1000;j++){
a[i][j]=read();
}
}
printf("time used=%.3fs\n",double(clock()-s)/CLOCKS_PER_SEC);
}
运行后的结果以下:
如今这个方法只需0.163s,比其余的方法都快,并且不会在评测机上出现问题,而且也没有调用许多函数
遇到数据量大的题,尽可能用手写的快速读入来读取