快速讀入詳解


當你在信息學競賽\((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()\)來負責讀入。

在實際的文件中,會有許多不必要的隱藏字符,比如換行符\n等。

因此,我們需要先排除掉這些字符,也就是第一個\(while\)循環。但是有一個特例:\(-21904\)中的\(-\)號。這個負號不是數字啊!於是我們用\(w\)當數的符號。有負號時,\(w\)從原來的\(1\)轉化成了\(-1\)

於是,我們要特判!if(ch == ‘-’) w = -1;這就是判負號的語句。

下一個循環中,就是位值原理。數\(\overline{abcd} = 10 \times (10 \times (10 \times a + b) + c) + d\),讀者自證不難。

最后返回\(n = sgn(n) \times |n|\),其中\(sgn(x)\)\(x\)的符號。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM