关于scanf("百分号1d")的读入效率问题(使用快读的大佬请跳过)

在比赛中我们常常会遇到这样的输入格式:给出一个n行m列01矩阵,且这个矩阵相邻元素间无空格。
比如说这样的:
3 3
101
011
110
这时候就无法用%d读入了……
而我们知道c++有一种冷门的读入方法 scanf(“%1d”,&x) 。
为了方便,我曾多次这样读01矩阵,结果这次模拟赛的某一题,由于%1d的效率问题,我从100分TLE到了61…Orz
然后我惊讶的发现某度上并无关于%1d的读入效率说明(可能是太冷门了吧),所以我测试了一下%1d的效率。

用%1d读入的代码:

#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",n,m);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            printf("%d",rand()&1);
        }
        printf("\n");
    }
    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

可以看出当数据范围很大时,%1d的读入要比读入字符慢很多倍,这种效率是竞赛中难以承受的,所以还是要尽量避免使用%1d,虽然一个个读字符会让程序变得很丑

你可能感兴趣的:(常见技巧)