首页 > 其他分享 >P10815 快速读入

P10815 快速读入

时间:2024-09-17 12:13:43浏览次数:8  
标签:ch P10815 cout cin while 读入 缓冲区 快速 getchar

C++标准库提供了强大的输入输出方法。但是,出于设计与安全上的原因,它们的性能不一定能满足算法竞赛的需求,因此在面对巨大的输入输出文件时可能需要考虑优化。

注意

  1. 通常来说,不必特别在意读写优化。
  2. 如果习惯 cin/cout 的话,在文件较大时记得关闭流同步,使用 '\n' 而不是 endl
  3. 输入输出文件大小十分极端时,才需要考虑手写读写优化。这通常意味着输入输出文件超过了 \({10}^{6}\) 个 int ,即使在这个量级下,手写输入与标准库的差距仍通常不到0.1s。

当然,可以通过以下代码关闭流同步提升 cin/cout 性能。关闭流同步后,cin/cout 会拥有自己的缓冲区,与 scanf/printf 混用会带来异常。

ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
  1. cout<<endl; 会使用系统调用刷新输出缓冲区,输出大量换行时非常缓慢。

如果需要手写输入函数,使用getchar读取整数是一个有效减少输入时间的手段。

template<typename T1>
void read(T1 &x){
    char c;
    c=getchar();
    bool flag=1;//是否为正数
    while(c<'0'||c>'9'){//在整数前通常有一些其它字符
        if(c=='-'){
            flag=0;
        }
        c=getchar();
    }
    x=0;
    while(c>='0'&&c<='9'){
        x=(x<<1)+(x<<3)+c-'0';//使用位运算优化x*10
        c=getchar();
    }
    x=flag?x:(-x);
}

注意:
在输入到达文件结束时继续读取,getchar()会返回-1,导致死循环。如果遇到输入可能不完整的情况,需要在第一个while里判断EOF。

上面的程序中 getchar() 仍可以优化。stdio库里维护了一个缓冲区,以减少读取硬盘的次教:我们可以自己调用 fread ,来进一步减少读取硬盘的次数和标准库边界检查的时间。标准库些里通常缓冲区的大小为8KiB,事实上这是一个合理的大小:更大的缓冲区性能提升非常小。我们可以选择稍大一些的2的次幂作为缓冲区的大小。

const int SIZE=1<<14;//16Kib
char getc(){
    static char buf[SIZE],*begin=buf,*end=buf;
    if(begin==end){
        begin=buf;
        end=buf+fread(buf,1,SIZE,stdin);
    }
    return *begin++;
}

使用以上代码中的 getc() 函数替代 getchar() ,可以获得部分性能提升。

如果评测系统为Linux,可以考虑直接使用getchar_unlocked()替代getchar(),效率接近fread。这是一种放弃了线程安全的函数,但是对算法竞赛来说没有弊端。

知道了上述原理,我们就可以写出此题代码了:

#include<bits/stdc++.h>
using namespace std;
inline int read(){
    int x=0;
    bool b=false;
    char ch=getchar_unlocked();
    while(ch<'0'||ch>'9'){
        if(ch=='-') b=true;
        ch=getchar_unlocked();
    }
    while(ch>='0'&&ch<='9'){
        x=(x<<1)+(x<<3)+ch-'0';
        ch=getchar_unlocked();
    }
    if(b) return -x;
    else return x;
}
int main(){
    int n,sum=0;
    n=read();
    while(n--) sum+=read();
    printf("%d\n", sum);
    return 0;
}

标签:ch,P10815,cout,cin,while,读入,缓冲区,快速,getchar
From: https://www.cnblogs.com/cly312/p/18417051

相关文章

  • 如何自己快速搭建上线小程序?怎么用最低的成本搭建自己的小程序?个人如何通过个体工商主
    自2017年1月9日上线以来,微信小程序极大地便利了人们的日常生活,并为众多商家开辟了全新的推广和销售产品的渠道。然而,许多用户由于缺乏技术背景,常常感到无从下手,想要自己创建一个小程序却不知道如何进行。那么,如何才能成功建立一个属于自己的微信小程序呢?今天,我将详细分享创建......
  • 最新微信群发群发引流工具,解放双手快速引流
    本文介绍了一款微信群管理助手软件,该软件提供了一系列自动化功能,旨在帮助用户更高效地管理微信群和好友。功能概述微信群管理助手软件是一款专为微信用户设计的管理工具,通过自动化技术简化微信群的日常操作。主要功能一键自动加微信群:快速加入多个微信群,提高社交效......
  • 快速入门 QT5 C++基础
    1.QT5中文显示乱码方法一:system("chcp65001");//放在主函数中方法二:首先引入库  #include"windows.h"再在主函数中写 SetConsoleOutputCP(CP_UTF8);2.什么是类,如何创建一个类#include<iostream>#include"windows.h"usingnamespacestd;classDog{/......
  • 鸿蒙应用开发快速学习指南(初级篇-7 从网络获取数据)
    从网络获取数据第七课:从网络获取数据本节课的内容主要是如何使用http请求模块,依旧是从习题开始。判断题在http模块中,多个请求可以使用同一个httpRequest对象,httpRequest对象可以复用:正确(True)错误(False)从没有听过这种说法,选错误。拿下。使用on(type:‘headersRec......
  • 信息学奥赛初赛天天练-90-CSP-S2023基础题2-离散数学、染色、完全三叉树、平面图、边
    PDF文档公众号回复关键字:202409152023CSP-S选择题1单项选择题(共15题,每题2分,共计30分:每题有且仅有一个正确选项)6以下连通无向图中,()一定可以用不超过两种颜色进行染色A完全三叉树B平面图C边双连通图D欧拉图7最长公共子序列长度常常用来衡量两个序列的相......
  • 【第35章】Spring Cloud之Seata-Server快速入门
    文章目录前言一、准备1.架构图2.工作机制3.Seata术语4.事务模式4.1SeataAT模式(依赖数据库)4.2SeataTCC模式(不依赖数据库)4.3SeataSaga模式(支持长事务)4.4SeataXA模式(支持XA协议)二、安装1.下载2.解压3.重要属性4.修改配置4.1配置中心4.2注......
  • 快速掌握类和对象
    目录1.面向对象的概念1.1面向对象的编程步骤2.类2.1类的详解2.2类的实例化---对象3.对象3.1对象的构造及初始化3.2构造方法3.3默认初始化4.this关键字5.static关键字5.1为什么要有static5.2static修饰成员变量---类变量5.3static修饰成员方法---类......
  • 第307题|快速掌握 反常积分敛散性判定的方法|武忠祥老师每日一题
    解题思路:先判断这个反常积分的敛散性,再讨论a的取值范围;判断反常积分的敛散性,我们通常有三个方法:(1)根据定义,通常在原函数比较好求的情况下,可以根据定义(2)比较判别法,(3)p积分,这不是p积分。所以我们使用比较判别法来做这道题。0是无界点,又有无穷区间,既有无界函数的积分也有无......
  • 数据结构之快速排序、堆排序概念与实现举例
    1、快速排序快速排序是一种高效的排序算法,采用分治法策略。它的基本思想是:通过一个划分操作,将待排序的数组分为两个(尽可能)均等的子数组,使得左侧子数组中的所有元素都不大于右侧子数组中的任何元素,然后对这两个子数组分别进行快速排序,整个排序过程可以递归进行,以此达到整个......
  • Elasticsearch和向量数据库的快速入门
    在比较Elasticsearch和向量数据库之前,让我们简要解释它们是什么:什么是Elasticsearch?Elasticsearch是一个流行的开源搜索和分析引擎,建立在ApacheLucene之上。它专为全文搜索、分析和日志分析用例而设计。主要特点:文档导向的NoSQL数据库分布式和可扩展的架构实时搜索和分析无需......