• 快速读入详解


    当你在信息学竞赛((OI))中进入了提高组时,你可能会被卡常!

    卡常!

    程序被卡常数,一般指程序虽然渐进复杂度可以接受,但是由于实现/算法本身的时间常数因子较大,使得无法在OI/ICPC等算法竞赛规定的时限内运行结束。

    常数被称为计算机算法竞赛之中最神奇的一类数字,主要特点集中于令人捉摸不透,有时候会让水平很高的选手迷之超时或者超空间。

    ​ ——来自某度百科……

    快速读入

    简称快读,是信息学竞赛中卡常数最为常见的方法。

    一般来讲,大多数题目的出题人都不会到这种丧心病狂的地步。

    不过,以防万一肯定没坏处啊~ 反正代码很简单啦

    代码

    先上代码!讲解在后面。

    inline int read(){
        int s = 0, w = 1; char ch = getchar();
        while(ch < '0' || ch > '9'){ if(ch == '-') w = -1; ch = getchar();}
        while(ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
        return s * w;
    } // 这是能判负数的C++快读模板
    

    在代码中,只需将cin >> nscanf("%d", &n)改成n = read()即可!

    原理分析

    为什么(cin)慢?因为它需要和(stdio)保持同步,也就是sync_with_stdio

    为什么(scanf)慢?原因有点复杂。

    1. 它可以接受多种形式的输入(数字、字符串等等),因此需要判断。
    2. 它因为某些安全原因——输入太快可能会有些玄学的(bug),具体的我也不太清楚。

    其实在(C++)中,依次读入单个字符是比一次读入一个数要快的,因此我们可以用(getchar())来负责读入。

    在实际的文件中,会有许多不必要的隐藏字符,比如换行符 等。

    因此,我们需要先排除掉这些字符,也就是第一个(while)循环。但是有一个特例:(-21904)中的(-)号。这个负号不是数字啊!于是我们用(w)当数的符号。有负号时,(w)从原来的(1)转化成了(-1)

    于是,我们要特判!if(ch == ‘-’) w = -1;这就是判负号的语句。

    下一个循环中,就是位值原理。数(overline{abcd} = 10 imes (10 imes (10 imes a + b) + c) + d),读者自证不难。

    最后返回(n = sgn(n) imes |n|),其中(sgn(x))(x)的符号。

  • 相关阅读:
    get post 小结
    ddt 实例
    通俗大白话来理解TCP协议的三次握手和四次断开
    find xss
    use . adb . get wifi
    http bass
    mac 配置homebrew
    id 与 void * 转换
    Maven
    percent-encode 百分号编码
  • 原文地址:https://www.cnblogs.com/newbiePWang/p/10192655.html
Copyright © 2020-2023  润新知