小技巧-讀優與寫優
讀優與寫優
讀優與寫優是面對輸入或者輸出資料規模比較巨大的時候,cin和cout會TLE,即使是scanf和printf也會浪費大量時間,這時我們就可以使用讀優與寫優
一個小小的冷知識
cin和cout之所以慢,是因為它有很多的保險設定,浪費了時間,所以只要加入這段程式碼
1 std::ios::sync_with_stdio(false);
這樣就可以取消cin和cout的保險裝置
正經的讀優與寫優
原理
用cin和cout或者scanf和printf讀寫單個數字時,速度會比getchar和putchar讀寫單個字元慢很多,考慮到比起讀寫的時間,運算的時間幾乎可以忽略不計,那麼我們可以使用getchar和putchar按數位輸入輸出,加快讀寫速度
讀入優化
基本原理
使用一個while過濾掉所有非數字的字元,並且判斷正負,再用一個while把數字*10並讀入下一位。這樣我們需要一個字元變數來讀入,需要兩個整數變數來儲存符號和數字的絕對值
程式碼
1 inline int qread() 2 { 3 char ch = getchar(); 4 int f = 1, x = 0;//f符號x絕對值 5 while(!(ch >= '0' && ch <= '9')) 6 { 7 if(ch == '-') f = -1;//判斷符號8 ch = getchar(); 9 } 10 while(ch >= '0' && ch <= '9') 11 { 12 x *= 10; 13 x += (ch & 15);//&15相當於-'0',也就是字元轉換成數字 14 ch = getchar(); 15 } 16 return f * x; 17 }
這就是常用的讀優了。然而如果你比較懶,可以使用<cctype>庫裡面的isdigit(char)函式來判斷一個字元是否是數字,但是可能對於低版本的編譯器會出現一些玄學bug,所以還是推薦手動判斷在'0'和'9'之間,這樣,想讀入一個int a,就可以這樣
1 a = read();
如果你的整數時long long不是int,那麼把讀優函式型別和函式裡面的int全部換成long long,就OK了。讀優是一個很常用的操作,可以解決很多由於資料量大而TLE的問題。
輸出優化
其實寫入優化遠不如讀入優化常用,因為很多人懶得寫。。。再說很多題是讀入一堆,輸出只有每行一個數。。。
一些改變
如果像讀入優化一樣按位輸出,你會發現所有數字反了過來。如果寫一個棧來存數,反而弄巧成拙了,那麼可以用遞迴來實現
程式碼實現
我對面那臺電腦上的大佬隨手用遞迴寫了一個寫優函式
1 void print(int n) 2 { 3 if(n==0) return; 4 print(n/10); 5 putchar(n%10+'0'); 6 }
我一看,實屬巧妙,它會把這個數字按照正確的順序從左往右輸出。然而,當數字為0的時候,它會什麼也輸出不出來,如果是負數會炸掉,所以我給它加工了一下
1 inline void print(int n) 2 { 3 if(n==0) return; 4 print(n/10); 5 putchar(n%10+'0'); 6 } 7 inline void qwrite(int n) 8 { 9 if(n==0) 10 { 11 putchar('0'); 12 return; 13 } 14 if(n<1) 15 { 16 putchar('-'); 17 n*=-1; 18 } 19 print(n); 20 }
這樣,需要輸出一個整數a時,就可以這樣實現了
1 qwrite(a);
重點!重點!重點!小數千萬不要使用讀寫優化!這個讀寫優化只能用於整數!