scanf(「パーセント1 d」)の読み込み効率の問題について(速読を使う大物はスキップしてください)
4451 ワード
試合中、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で読み込まれたコード:
%cでcharを読んでintのコードを強く回します:
元のデータジェネレータ
結果は次のとおりです.
データ範囲
%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つの読み取り文字はプログラムを醜くしますが.
%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つの読み取り文字はプログラムを醜くしますが.