对拍详解

像我这种以不认真而闻名的人,就应该练就一手优秀的调试技能

对拍作为一种优秀的查错方式,不仅可以在日常训练中找出自己改不出的程序的错,在考试中更能验证自己一种高效率解法的正确性,常言道:

              一个人的程序能过对拍,基本上拿高分没问题,除非他被卡

                          ————我自己
然后之前一次考试因为对拍是加了<windows.h>,直接CE痛失100分,所以我又认真学了一下Linux的对拍方式。
那就来看看如何愉快的对拍吧O(∩_∩)O~~
  • 基本程序

 用vscode举例:

1.正确代码

暴力出奇迹
#include <bits/stdc++.h>
using namespace std;
int main(){
    freopen("input.txt","r",stdin);
    freopen("right.txt","w",stdout);
    int a,b;
    cin >> a >> b;
    cout << a+b;
    return 0;
}
//文件生成名为 yes

2.待拍代码

检验正确性

#include <bits/stdc++.h>
using namespace std;
int main(){
    freopen("input.txt","r",stdin);
    freopen("wrong.txt","w",stdout);
    int a,b;
    cin >> a >> b;
    if(b%100==0) b++;
    cout << a+b;
    return 0;
}
//文件生成名为no

3.造数据代码

这里是个技术活,后面会详细列举一些常用造数据方式

最基础的方式就是随机数生成

函数srand(time(NULL))使得程序重置随机种子

要取得[a,b)的随机整数,使用(rand() % (b-a))+ a;
要取得[a,b]的随机整数,使用(rand() % (b-a+1))+ a;
要取得(a,b]的随机整数,使用(rand() %4 (b-a))+ a + 1;
通用公式:a + rand() % n;其中的a是起始值,n是整数的范围。
要取得a到b之间的随机整数,另一种表示:a + (int)b * rand() / (RAND_MAX + 1)。
要取得0~1之间的浮点数,可以使用rand() / double(RAND_MAX)。

其中RAND_MAX是一个不小于32767的整数常量,一般在Windows中为32767,类Unix系统中为2147483647

这里先展示个简单的:

#include <bits/stdc++.h>
using namespace std;
int main(){
    freopen("input.txt","w",stdout);
    srand(time(NULL));
    int x=rand()%1000+1,y=rand()%1000+1;
    cout << x << " " << y;
    return 0;
}
//生成名为make

4.比较代码

linux环境:

#include <bits/stdc++.h>
using namespace std;
int main(){
    freopen("test.txt","w",stdout);
    int tot=0;
    while(tot<1000){//拍1000个数据点
        tot++;
        printf("text %d :",tot);
        system("./make");
        double st1=clock();
        system("./yes");
        double ed1=clock();
        double st2=clock();
        system("./no");
        double ed2=clock();
        if(system("diff right.txt wrong.txt")){
            printf("Wrong Answer\n"); return 0;
        }
        else printf("Accepted; yes:%.0lfms wrong:%.0lfms\n",ed1-st1,ed2-st2);
    }   //正解用时和错解用时
    return 0;
}
//生成名为check

windows环境:

#include <bits/stdc++.h>
#include <windows.h>
using namespace std;
int main(){
    freopen("test.txt","w",stdout);
    int tot=0;
    while(tot<1000){//拍1000个数据点
        tot++;
        printf("text %d :",tot);
        system("make.exe");
        double st1=clock();
        system("yes.exe");
        double ed1=clock();
        double st2=clock();
        system("no.exe");
        double ed2=clock();
        if(system("fc right.txt wrong.txt")){
            printf("Wrong Answer\n"); return 0;
        }
        else printf("Accepted; yes:%.0lfms wrong:%.0lfms\n",ed1-st1,ed2-st2);
    }   //正解用时和错解用时
    return 0;
}
//生成名为check

当然也有简单一点的,比赛一般用这个:

#include <bits/stdc++.h>
using namespace std;
int main(){
    freopen("test.txt","w",stdout);
    while(1){//拍到错为止
        system("./make");
        system("./yes");
        system("./no");
        double ed2=clock();
        if(system("diff right.txt wrong.txt")){
            printf("WA");return 0;//此时input.txt里就是错误数据
        }
    }
    return 0;
}
//生成名为check

在vscode中可以建立多个终端,实现一个程序对拍时不影响别的程序运行

右下角的check正在运行,但丝毫不影响我work程序的运行

然后就可以愉悦的查错了

一定注意要把这几个文件放在同一个文件夹下!!!!!

  •  随机数据制作

对于不同题目,可以针对性的进行不同的造数据,下面列举几个常用的:

1.随机数生成

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int getint(int l,int r){//生成[l,r]的整数
    return (rand()%(r-l+1))+l; 
    /*
    windows下可以:
    return ((rand()*rand())%(r-l+1)+l)
    */
}
ll getll(ll l,ll r){//长整型
    return ((rand()*rand())%(r-l+1)+l);//windows多乘两个rand();
}
double getdb(int l,int r){//实数
    int k=(rand()%(r-l))+l; 
    return k+rand()/double(RAND_MAX);
}
int main(){
    freopen("input.txt","w",stdout);
    srand(time(NULL));
    for(int i=1;i<=10;i++){
        printf("%d\n",getint(5,100));
    }
    for(int i=1;i<=10;i++){
        printf("%lld\n",getll(100000000000,1000000000000000));
    }
    for(int i=1;i<=10;i++){
        printf("%.2lf\n",getdb(30,50));
    }
    return 0;
}
/*
运行结果:
52
93
65
53
93
89
65
35
82
67
99244226334
101639251471
98519266504
100149053732
101786207246
101359426951
98461830119
102091349424
100860361060
100699029762
39.09
36.00
32.12
47.26
35.05
47.33
34.19
44.46
48.84
33.69
*/
View Code

2.建图

#include <bits/stdc++.h>
using namespace std;
const int M = 1e6+100;
typedef long long ll;
int get(int l,int r){
    return (rand()%(r-l+1))+l; 
}
pair<int,int> e[M];
map <pair<int,int>,bool> h;
int main(){
    freopen("input.txt","w",stdout);
    srand(time(NULL));
    int n=get(1,20);
    int m=get(n,n*2);
    printf("%d %d\n",n,m);
    for(int i=1;i<n;i++){
        int fa=get(1,i);
        e[i]=make_pair(fa,i+1);
        h[e[i]]=h[make_pair(i+1,fa)]=1;//去重
    }
    for(int i=n;i<=m;i++){
        int x,y;
        do{
            x=get(1,n),y=get(1,n);
        }while(x==y||h[make_pair(x,y)]);
        e[i]=make_pair(x,y);
        h[e[i]]=h[make_pair(y,x)]=1;
    }
    //随机打乱
    random_shuffle(e+1,e+m+1);
    for(int i=1;i<=m;i++) printf("%d %d\n",e[i].first,e[i].second);
    return 0;
}

 

posted @ 2022-07-09 10:27  blue_tsg  阅读(911)  评论(3编辑  收藏  举报