然鹅,我搜遍全网也没有找出来几篇,所以到了我为这份事业做出一丝贡献的时候了hiahiahiahia~
(博主在发疯ing,请勿理会)
好了我们开始进入正题:如何写好一份对拍程序呢?
其实很简单,我们就以史上最简单的题目a+b来举例子
首先,我们要准备四份代码(加上对拍代码)
这篇文章中我们将主要讲一下后面两份代码的写法
首先,我们想要完成一次对拍需要先有一个主程序和副程序若以a+b为例:
我的程序 --> 主程序(wrong)
my.cpp
#include
using namespace std;
int main () {
srand ((unsigned) time(0));
int a, b;
cin >> a >> b;
if (!random (10)) {//随机数生成,会导致代码有1/10的概率出错
cout << 1 << endl;
}
else cout << a + b << endl;
return 0;
}
正解或暴力 --> 副程序(right)
#include
using namespace std;
int main () {
int a, b;
cin >> a >> b;
cout << a + b << endl;
return 0;
}
好了,至此,前戏都已经结束了,该重头戏了qaq
首先,随机数生成分许多种,分为生成数列,生成无向/有向图,生成树,生成区间列…
在此我们只讲这四种(因为我只会这四种,,
其实,这些随机数生成程序都是大同小异的
所有随机数生成程序都包含以下内容:
#include //头文件主要会用到cstdlib和ctime的内置函数
#define ll long long
ll random (ll n){ // 有些题的数据可能会爆int,所以用ll会更保险些
return rand() * rand() % n;
}
int main () {
srand ((unsigned) time(0));//随机数种子,用time(0)的话会不断更新你的随机数
//具体内容...
}
插播一条对srand的解释:srand释义
然后就是随机生成各类型的板子(你没有听错,就是板子!!!)
一. 随机生成整数序列
在上述板子的基础上随机生成n<=1e5个绝对值在1e9之内的整数
int n = random(100000)+1;
int m = 1000000000;
cout << n << endl;
for (int i = 1; i <= n; i++) {
int a = random(2*m+1)-m;
cout << a << endl;
}
二.随机生成区间列
在上述板子的基础上随机生成m个[1,n]的子区间
for (int i = 1; i <= m; i++) {
int l = random(n) + 1;
int r = random(n) + 1;
if (r < l) swap(l, r);
cout << l << " " << r << endl;
}
(剩下两个就留给大家自己思考吧qaq,在此非常感谢lyd大佬写的进阶指南给了我很多启发)
终于,我们到了这篇文章要讲的地方(哭了
首先,假设我们看到这里的人都已经写好了前面三个程序
分别为:
my.cpp(自己可能会出错的程序)
bf.cpp(暴力或正解)
rand.cpp(随机数生成程序)
此时,我们需要建一个文件夹,将这些程序都存起来(一会的对拍程序也要放在一起)
首先,我们来看lyd大佬在进阶指南里所用的写法:
#include
using namespace std;
int main () {
for (int i = 1; i <= 10000; i++) {
system ("C:\\rand.exe");
double st = clock();
system ("C:\\my.exe");
double ed = clock();
system ("C:\\bf.exe");
if (system ("fc C:\\data.out C:\\data.ans")){
puts ("Wrong Answer!");
return 0;
}
else {
printf ("Accepted #%d, %.0lfms\n", i, ed-st);
}
}
return 0;
}
其实我赶脚这种写法就有点麻烦了,因为我们需要在my和bf中用文件输入输出,虽然比赛的时候基本都要用吧qaq
不过还有另一种写法:
#include
#include
using namespace std;
int main(){
while(1) {
system("data.exe > data.txt");
system("biaoda.exe < data.txt > biaoda.txt");
system("test.exe < data.txt > test.txt");
if(system("fc test.txt biaoda.txt")) break;
}
cout<<"WA"<
至于这种就显得太过简洁
所以,此处就看你们的喜好了qaq
谢谢各位的阅读!
文末致谢:
lyd大佬写的算法竞赛进阶指南让我学到了许多
@kongfanyu 所写的 关于srand(time(0)) rand() 的解释
@sky-edge 所写的 对拍程序的写法