NOIP比赛中如何加速c++的输入输出
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,比其他的方法都快,而且不会在评测机上出现问题,并且也没有调用许多函数 
遇到数据量大的题,尽量用手写的快速读入来读取
总结
- 遇到大数据时尽量避免用cin
- noip比赛中坚决不要写std::ios::sync_with_stdio(false)来优化cin
- 如果是double或输入格式较复杂用scanf
- 遇到数据量大的题,且是long long或int,尽量用手写的快速读入来读取
NOIP比赛中如何加速c++的输入输出的更多相关文章
- [ACM训练] ACM中巧用文件的输入输出来改写acm程序的输入输出 + ACM中八大输入输出格式
		ACM中巧用文件的输入输出来改写acm程序的输入输出 经常有见大神们使用文件来代替ACM程序中的IO,尤其是当程序IO比较复杂时,可以使自己能够更专注于代码的测试,而不是怎样敲输入. C/C++代码中 ... 
- 新手数据比赛中数据处理方法小结(python)
		第一次参加,天池大数据竞赛(血糖预测),初赛排名1%.因为自己对python不熟悉,所以记录一下在比赛中用到的一些python方法的使用(比较基础细节,大佬绕道): 1.数据初探 data.info( ... 
- 【CTF 攻略】CTF比赛中关于zip的总结
		[CTF 攻略]CTF比赛中关于zip的总结 分享到: --> 本文首发于安全客,建议到原地址阅读,地址:http://bobao.360.cn/ctf/detail/203.html 前言 ... 
- java:比赛中常用方法整理——字符串(基础)
		一.将字符串转化为字符数组: toCharArray返回一个字符数组. char[] a=J.toCharArray(); 二.字符串的长度 字符串的长度和字符数组的长度是不一'样'的. 字符串长度( ... 
- java:编程比赛中有用的方法整理(一)数组
		我曾经参加过几次编程比赛,但是当时用的是c语言,现在学习了java,打算专攻java组,故以此整理. 数组无论在哪里都必不可少. 一.数组的拷贝: 使用Arrays类的copyOf方法: 1.将一个数 ... 
- linux内核中的最简单的输入输出调度算法noop
		1. noop是什么? noop是一种输入输出调度算法 2. noop的别称 又称为电梯调度算法 3. noop原理是怎样的? 将输入输出请求放到一个FIFO队列中,然后按次序执行队列中的输入输出请求 ... 
- 记intel杯比赛中各种bug与debug【其一】:安装intel caffe
		因为intel杯创新软件比赛过程中,并没有任何记录.现在用一点时间把全过程重演一次用作记录. 学习 pytorch 一段时间后,intel比赛突然不让用 pytoch 了,于是打算转战intel ca ... 
- cmd中pip加速的方法
		临时加速: pip install dlib -i https://pypi.tuna.tsinghua.edu.cn/simple/ 永久加速: 在user文件夹里新建pip文件夹,再建pip.in ... 
- ACM、OI等比赛中的程序对拍问题
		多年前请教于ZXYTIM(zxy)大牛,现在把windows环境下的版本贴出来. 手动数据调试效率太低,程序对拍还是非常实用的,特别适用于OI.蓝桥杯等这些比赛规则.可以用于暴力与AC算法之间的对拍. ... 
随机推荐
- 使用appium+python做UI自动化的demo
			使用appium+python做UI自动化的demo 案例使用的知乎app,下载最新的知乎apk,存在了电脑上,只需要配置本机上app目录,不需要再配置appPackage和appActivity # ... 
- python 监听键盘事件pyHook
			#coding=utf- import pyHook import pythoncom # 监听到鼠标事件调用 def onMouseEvent(event): if(event.MessageNam ... 
- 一句话题解&&总结
			CF79D Password: 差分.两点取反,本质是匹配!最短路+状压DP 取反是套路,匹配是发现可以把操作进行目的化和阶段化,从而第二次转化问题. 且匹配不会影响别的位置答案 sequence 计 ... 
- elasticsearch文档冲突
			https://www.elastic.co/guide/cn/elasticsearch/guide/current/optimistic-concurrency-control.html当我们之前 ... 
- 动态连通性问题——算法union-find
			问题定义:问题的输入是一列整数对,其中每个整数都表示一个某种类型的对象,一对整数p,q可以被理解为"p和q是相连的".我们假设“相连”是一种对等的关系. 这也意味着它具有: 1.自 ... 
- Java锁优化
			Java锁优化 应用程序在并发环境下会产生很多问题,通常情况下,我们可以通过加锁来解决多线程对临界资源的访问问题.但是加锁往往会成为系统的瓶颈,因为加锁和释放锁会涉及到与操作系统的交互,会有很大的性能 ... 
- Java NIO学习笔记八   DatagramChannel
			Java NIO DatagramChannel Java NIO DatagramChannel是可以发送和接收UDP数据包的通道.由于UDP是一种无连接网络协议,因此您不能默认读取和写入Datag ... 
- PAT 甲级 1029 Median (25 分)(思维题,找两个队列的中位数,没想到)*
			1029 Median (25 分) Given an increasing sequence S of N integers, the median is the number at the m ... 
- vim  全局替换
			:%s/foo/bar/g 把全部foo替换为bar,全局替换 
- UIApearance的认识
			在参加工作之前一直不知道还有UIApearance的这个属性,并且不知道UIApearance是用来干嘛的,还不知道怎么用,工作之后,看公司代码中都会出现这个UIApearance,我决定学习学习,并 ... 
