scanf(「パーセント1 d」)の読み込み効率の問題について(速読を使う大物はスキップしてください)


試合中、n行m列01行列を与え、この行列の隣接要素間にスペースがない入力フォーマットに遭遇することが多い.例えば、3 3 101 011 110では%dでは読み込めませんが...c++には冷たいドアの読み込み方法scanf("%1 d",&x)があることがわかります.便宜上、私は何度もこのように01行列を読んだことがありますが、今回のシミュレーション試合のある問題で、%1 dの効率の問題で、100分TLEから61に着きました...Orzそして、ある度%1 dの読み込み効率についての説明がないことに驚きました(あまりにも冷たいのかもしれませんが)、私は%1 dの効率を測ってみました.
%1 dで読み込まれたコード:
#include
using namespace std;

int n,m;

int main(){
    freopen("test.in","r",stdin);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            int x;
            scanf("%1d",&x);
        }
    }
    return 0;
}

%cでcharを読んでintのコードを強く回します:
#include
using namespace std;

int n,m;

int main(){
    freopen("test.in","r",stdin);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            int x;
            char y=' ';
            while(y!='0'&&y!='1')scanf("%c",&y);
            x=y-'0';
        }
    }
    return 0;
}

元のデータジェネレータ
#include
using namespace std;

int n,m;

int main(){
    freopen("test.in","w",stdout);
    scanf("%d%d",&n,&m);
    printf("%d %d
"
,n,m); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ printf("%d",rand()&1); } printf("
"
); } return 0; }

結果は次のとおりです.
データ範囲
%1d
%c
n=m=100
0.21s
0.16s
n=m=500
0.27s
0.20s
n=m=1000
0.54s
0.31s
n=m=2000
1.64s
0.71s
n=m=5000
9.16s
3.40s
まあもっと大きいデータはうちの旦那様機のrand()が短時間で出てこないので測れない...これもrand()の効率がどれほど低いかを証明しています...STO
データ範囲が広い場合、%1 dの読み込みは読み取り文字よりも何倍も遅いことがわかります.この効率は競合では耐えられないので、%1 dの使用はできるだけ避けなければなりません.1つの読み取り文字はプログラムを醜くしますが.