对拍详解
像我这种以不认真而闻名的人,就应该练就一手优秀的调试技能
对拍作为一种优秀的查错方式,不仅可以在日常训练中找出自己改不出的程序的错,在考试中更能验证自己一种高效率解法的正确性,常言道:
一个人的程序能过对拍,基本上拿高分没问题,除非他被卡
————我自己
然后之前一次考试因为对拍是加了<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 */
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; }
This is your dream.Anything you can dream,you can do it now.