NOIP比赛中如何加速c++的输入输出

在竞赛中,遇到大数据时,往往需要更快的读取方式。由于比赛中输出一般规模较小,本文只讨论输入如何加速.

现在我们生成1000000个随机数,构成1000*1000的矩阵,然后输入比较时间(Win 10系统)

#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的速度

在比赛中,经常出现数据集超大造成 cin TLE的情况。这时候大部分人(包括原来我也是)认为这是cin的效率不及scanf的错

准确的说,cin在不优化的情况下效率是很低的,我们来测试一下

#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

有博客提到:

默认的时候,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

scanf的速度

既然noip比赛中坚决不要写std::ios::sync_with_stdio(false),那么我们可以用scanf

#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还是较快的

手写快速读入的速度

我们知道,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,比其他的方法都快,而且不会在评测机上出现问题,并且也没有调用许多函数

遇到数据量大的题,尽量用手写的快速读入来读取

总结

  1. 遇到大数据时尽量避免用cin
  2. noip比赛中坚决不要写std::ios::sync_with_stdio(false)来优化cin
  3. 如果是double或输入格式较复杂用scanf
  4. 遇到数据量大的题,且是long long或int,尽量用手写的快速读入来读取

NOIP比赛中如何加速c++的输入输出的更多相关文章

  1. [ACM训练] ACM中巧用文件的输入输出来改写acm程序的输入输出 + ACM中八大输入输出格式

    ACM中巧用文件的输入输出来改写acm程序的输入输出 经常有见大神们使用文件来代替ACM程序中的IO,尤其是当程序IO比较复杂时,可以使自己能够更专注于代码的测试,而不是怎样敲输入. C/C++代码中 ...

  2. 新手数据比赛中数据处理方法小结(python)

    第一次参加,天池大数据竞赛(血糖预测),初赛排名1%.因为自己对python不熟悉,所以记录一下在比赛中用到的一些python方法的使用(比较基础细节,大佬绕道): 1.数据初探 data.info( ...

  3. 【CTF 攻略】CTF比赛中关于zip的总结

    [CTF 攻略]CTF比赛中关于zip的总结   分享到: --> 本文首发于安全客,建议到原地址阅读,地址:http://bobao.360.cn/ctf/detail/203.html 前言 ...

  4. java:比赛中常用方法整理——字符串(基础)

    一.将字符串转化为字符数组: toCharArray返回一个字符数组. char[] a=J.toCharArray(); 二.字符串的长度 字符串的长度和字符数组的长度是不一'样'的. 字符串长度( ...

  5. java:编程比赛中有用的方法整理(一)数组

    我曾经参加过几次编程比赛,但是当时用的是c语言,现在学习了java,打算专攻java组,故以此整理. 数组无论在哪里都必不可少. 一.数组的拷贝: 使用Arrays类的copyOf方法: 1.将一个数 ...

  6. linux内核中的最简单的输入输出调度算法noop

    1. noop是什么? noop是一种输入输出调度算法 2. noop的别称 又称为电梯调度算法 3. noop原理是怎样的? 将输入输出请求放到一个FIFO队列中,然后按次序执行队列中的输入输出请求 ...

  7. 记intel杯比赛中各种bug与debug【其一】:安装intel caffe

    因为intel杯创新软件比赛过程中,并没有任何记录.现在用一点时间把全过程重演一次用作记录. 学习 pytorch 一段时间后,intel比赛突然不让用 pytoch 了,于是打算转战intel ca ...

  8. cmd中pip加速的方法

    临时加速: pip install dlib -i https://pypi.tuna.tsinghua.edu.cn/simple/ 永久加速: 在user文件夹里新建pip文件夹,再建pip.in ...

  9. ACM、OI等比赛中的程序对拍问题

    多年前请教于ZXYTIM(zxy)大牛,现在把windows环境下的版本贴出来. 手动数据调试效率太低,程序对拍还是非常实用的,特别适用于OI.蓝桥杯等这些比赛规则.可以用于暴力与AC算法之间的对拍. ...

随机推荐

  1. 使用appium+python做UI自动化的demo

    使用appium+python做UI自动化的demo 案例使用的知乎app,下载最新的知乎apk,存在了电脑上,只需要配置本机上app目录,不需要再配置appPackage和appActivity # ...

  2. python 监听键盘事件pyHook

    #coding=utf- import pyHook import pythoncom # 监听到鼠标事件调用 def onMouseEvent(event): if(event.MessageNam ...

  3. 一句话题解&&总结

    CF79D Password: 差分.两点取反,本质是匹配!最短路+状压DP 取反是套路,匹配是发现可以把操作进行目的化和阶段化,从而第二次转化问题. 且匹配不会影响别的位置答案 sequence 计 ...

  4. elasticsearch文档冲突

    https://www.elastic.co/guide/cn/elasticsearch/guide/current/optimistic-concurrency-control.html当我们之前 ...

  5. 动态连通性问题——算法union-find

    问题定义:问题的输入是一列整数对,其中每个整数都表示一个某种类型的对象,一对整数p,q可以被理解为"p和q是相连的".我们假设“相连”是一种对等的关系. 这也意味着它具有: 1.自 ...

  6. Java锁优化

    Java锁优化 应用程序在并发环境下会产生很多问题,通常情况下,我们可以通过加锁来解决多线程对临界资源的访问问题.但是加锁往往会成为系统的瓶颈,因为加锁和释放锁会涉及到与操作系统的交互,会有很大的性能 ...

  7. Java NIO学习笔记八 DatagramChannel

    Java NIO DatagramChannel Java NIO DatagramChannel是可以发送和接收UDP数据包的通道.由于UDP是一种无连接网络协议,因此您不能默认读取和写入Datag ...

  8. PAT 甲级 1029 Median (25 分)(思维题,找两个队列的中位数,没想到)*

    1029 Median (25 分)   Given an increasing sequence S of N integers, the median is the number at the m ...

  9. vim 全局替换

    :%s/foo/bar/g 把全部foo替换为bar,全局替换

  10. UIApearance的认识

    在参加工作之前一直不知道还有UIApearance的这个属性,并且不知道UIApearance是用来干嘛的,还不知道怎么用,工作之后,看公司代码中都会出现这个UIApearance,我决定学习学习,并 ...