c++对拍讲解

话说身为一名oier,我们要学会的一个基础程序就是对拍QAQ

然鹅,我搜遍全网也没有找出来几篇,所以到了我为这份事业做出一丝贡献的时候了hiahiahiahia~
(博主在发疯ing,请勿理会)

好了我们开始进入正题:如何写好一份对拍程序呢?

其实很简单,我们就以史上最简单的题目a+b来举例子

首先,我们要准备四份代码(加上对拍代码)

  1. 你自己写的程序(可能会有问题)
  2. 从网上找的或自己写的保证无误的代码(注意,一定要保证正确性)
  3. 生成随机数的程序
  4. 对拍程序

这篇文章中我们将主要讲一下后面两份代码的写法

首先,我们想要完成一次对拍需要先有一个主程序和副程序若以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

重头戏

no.1 随机数生成

首先,随机数生成分许多种,分为生成数列,生成无向/有向图,生成树,生成区间列…
在此我们只讲这四种(因为我只会这四种,,

其实,这些随机数生成程序都是大同小异的
所有随机数生成程序都包含以下内容:

#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大佬写的进阶指南给了我很多启发)

no.2 对拍

终于,我们到了这篇文章要讲的地方(哭了

首先,假设我们看到这里的人都已经写好了前面三个程序
分别为:
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 所写的 对拍程序的写法

你可能感兴趣的:(一些凌乱不堪的东西)