scanf/printf比cin/cout快十倍多?

· · 闲话

看下面两篇代码,注意只有main函数里的输入输出不同
(可以只看下方main函数里的输入输出部分)

#include<iostream>
#include<cstdio>
#include<map>
#include<iomanip>
using namespace std;
int t;
int R[10005];
int D[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
map<string,int> mp;
int F[10005][15][35];
int YY[3660000],MM[3660000],DD[3660000];
int cnt;
void f1(){
    int y=2000,m=1,d=1;
    if(R[y]){
        D[2]=29;
    }
    else D[2]=28;
    while(1){
        ++d;
        if(d>D[m]){
            d=1;
            ++m;
            if(m>12){
                if(R[y]){
                    D[2]=28;
                }
                ++y;
                m=1;
                if(R[y]){
                    D[2]=29;
                }
            }
        }
        F[y][m][d]=++cnt;
        YY[cnt]=y;
        MM[cnt]=m;
        DD[cnt]=d;
        if(y==9999&&m==12&&d==31){
            return;
        }
    }
}
int main(){
//  freopen("date3.in","r",stdin);
//  freopen("date3.out","w",stdout);
    for(int i=1;i*4<=10000;++i){
        R[i*4]=1;
    }
    for(int i=1;i*100<=10000;++i){
        R[i*100]=0;
    }
    for(int i=1;i*400<=10000;++i){
        R[i*400]=1;
    }
    f1();
    cin>>t;
    int n;
    int s;
    while(t--){
        cin>>s>>n;
        int y=0,m=0,d=0;
        d=s%100;
        s/=100;
        m=s%100;
        s/=100;
        y=s;
        cout<<setfill('0')<<setw(4)<<YY[F[y][m][d]+n]<<setw(2)<<MM[F[y][m][d]+n]<<setw(2)<<DD[F[y][m][d]+n]<<endl;
    } 
    return 0;
}
#include<iostream>
#include<cstdio>
#include<map>
#include<iomanip>
using namespace std;
int t;
int R[10005];
int D[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
map<string,int> mp;
int F[10005][15][35];
int YY[3660000],MM[3660000],DD[3660000];
int cnt;
void f1(){
    int y=2000,m=1,d=1;
    if(R[y]){
        D[2]=29;
    }
    else D[2]=28;
    while(1){
        ++d;
        if(d>D[m]){
            d=1;
            ++m;
            if(m>12){
                if(R[y]){
                    D[2]=28;
                }
                ++y;
                m=1;
                if(R[y]){
                    D[2]=29;
                }
            }
        }
        F[y][m][d]=++cnt;
        YY[cnt]=y;
        MM[cnt]=m;
        DD[cnt]=d;
        if(y==9999&&m==12&&d==31){
            return;
        }
    }
}
int main(){
//  freopen("date3.in","r",stdin);
//  freopen("date3.out","w",stdout);
    for(int i=1;i*4<=10000;++i){
        R[i*4]=1;
    }
    for(int i=1;i*100<=10000;++i){
        R[i*100]=0;
    }
    for(int i=1;i*400<=10000;++i){
        R[i*400]=1;
    }
    f1();
    scanf("%d",&t);
    int n;
    int s;
    while(t--){
        scanf("%d%d",&s,&n);
        int y=0,m=0,d=0;
        d=s%100;
        s/=100;
        m=s%100;
        s/=100;
        y=s;
        printf("%d%d%d%d%d\n",YY[F[y][m][d]+n],MM[F[y][m][d]+n]/10,MM[F[y][m][d]+n]%10,DD[F[y][m][d]+n]/10,DD[F[y][m][d]+n]%10);
//      cout<<setfill('0')<<setw(4)<<YY[F[y][m][d]+n]<<setw(2)<<MM[F[y][m][d]+n]<<setw(2)<<DD[F[y][m][d]+n]<<endl;
    } 
    return 0;
}

第一段使用cin/cout输出的代码结果是

可以看到最后三个较大的数据点时间超限
第二段使用scanf/printf输出的代码结果是

可以看到最后三个测试点全部通过,并且用时都没有超过100ms
而本题的时间限制是正常的1s,也就是1000ms

如果代码时间超限,说明其运行时间超过了1000ms
也就是第一份代码运行时间超过了1000ms
但是第二份代码运行时间不到100ms
也就是第二份代码比第一份快十倍多
而两份代码唯一的区别就是输入输出方式不同
也就是scanf/printf比cin/cout快十倍多?

经过更多的测试,我们发现不使用endl并且关闭同步即可解决问题。

#include<iostream>
#include<cstdio>
#include<map>
#include<iomanip>
using namespace std;
int t;
int R[10005];
int D[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
map<string,int> mp;
int F[10005][15][35];
int YY[3660000],MM[3660000],DD[3660000];
int cnt;
void f1(){
    int y=2000,m=1,d=1;
    if(R[y]){
        D[2]=29;
    }
    else D[2]=28;
    while(1){
        ++d;
        if(d>D[m]){
            d=1;
            ++m;
            if(m>12){
                if(R[y]){
                    D[2]=28;
                }
                ++y;
                m=1;
                if(R[y]){
                    D[2]=29;
                }
            }
        }
        F[y][m][d]=++cnt;
        YY[cnt]=y;
        MM[cnt]=m;
        DD[cnt]=d;
        if(y==9999&&m==12&&d==31){
            return;
        }
    }
}
int main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
//  freopen("date3.in","r",stdin);
//  freopen("date3.out","w",stdout);
    for(int i=1;i*4<=10000;++i){
        R[i*4]=1;
    }
    for(int i=1;i*100<=10000;++i){
        R[i*100]=0;
    }
    for(int i=1;i*400<=10000;++i){
        R[i*400]=1;
    }
    f1();
    cin>>t;
    int n;
    int s;
    while(t--){
        cin>>s>>n;
        int y=0,m=0,d=0;
        d=s%100;
        s/=100;
        m=s%100;
        s/=100;
        y=s;
        cout<<setfill('0')<<setw(4)<<YY[F[y][m][d]+n]<<setw(2)<<MM[F[y][m][d]+n]<<setw(2)<<DD[F[y][m][d]+n]<<;
    } 
    return 0;
}

如果只将endl替换为'\n'或只关闭同步都将依然时间超限。