1. 程式人生 > >小技巧-讀優與寫優

小技巧-讀優與寫優

讀優與寫優

讀優與寫優是面對輸入或者輸出資料規模比較巨大的時候,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);

 重點!重點!重點!小數千萬不要使用讀寫優化!這個讀寫優化只能用於整數!