蒟蒻的sb对拍方法

今天就 CCF Online测试 了, 于是花了点时间复习下对拍。


对拍的目的:确保程序的正确性。

适用场景: 暴力容易写, 高效算法难调。


例子:

给定 \(n\) 个数\(a_1 \dots a_n\)\(m\) 次询问给定 \(x、y (保证 x \leq y)\), 求 \(\sum_{i=x}^y a_i\)

数据范围输入输出格式什么杂七杂八的先不管。

重要的是, 已经写出了比较牛逼的高分程序, 但是很慌,觉得很不稳, 就想人工测试下程序的正确性(不是静态查错法)。

如此, 就需要人造些(比较强的)测试数据。

一组测试数据要有输入和正确输出, 输入自然是用输入数据生成器来造, 输出就要写似乎绝对正确的程序跑出来。


这是“对拍”中最为核心的程序。

由于我将对拍所用到的程序都放在了一个文件夹里, 所以下面的运行才这么简单qwq(没写路径)

#include<bits/stdc++.h>
using namespace std;

int main()
{
	//xx.exe 是 xx.cpp 编译出来的可执行程序
	//rand 是输入数据生成器, 生成的输入数据保存在 test.in 里
	//sol 是不稳程序, 输出数据保存在 solans.out 里
	//bf 是可能很稳的暴力程序, 输出数据保存在 bfans.out 里
	for(int i=1; i<=100; ++i) {
		system("rand.exe");
		double st = time(0);
		system("sol.exe");
		double ed = time(0);
		system("bf.exe");
		if(system("fc solans.out bfans.out")) {
			cout << "WA\n";
			return 0;
		}
		cout << "AC!  timeused: " << ed-st << '\n';
	}
	return 0;
}

给出此题的输入数据生成器和暴力。(实际上, 这俩加起来似乎才算数据生成器)。

//输入数据生成器
//rand.cpp
#include<bits/stdc++.h>
using namespace std;

int rd(int n) { // 1 ~ n
	return rand() % n + 1;
}

int main()
{
	freopen("test.in","w",stdout);
	srand((unsigned)time(0));
	int n = rd(1000);
	cout << n << '\n';
	for(int i=1; i<=n; ++i) {
		int a = rd(1000);
		cout << a << ' ';
	}
	cout << '\n';
	int m = rd(1000);
	cout << m << '\n';
	for(int i=1; i<=m; ++i) {
		int x = rd(n), y = rd(n);
		if(x>y) swap(x,y);
		cout << x << ' ' << y << '\n';
	}
	fclose(stdin);
	fclose(stdout);
	return 0;
}
//似乎绝对正确的暴力
//bf.cpp
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1005;
int n, a[maxn];

int main()
{
	freopen("test.in","r",stdin);
	freopen("bfans.out","w",stdout);
	cin >> n;
	for(int i=1; i<=n; ++i) {
		scanf("%d", &a[i]);
	}
	int m; cin >> m; while(m--) {
		int x, y; scanf("%d%d", &x,&y);
		int ans = 0;
		for(int i=x; i<=y; ++i) ans += a[i];
		cout << ans << '\n';
	}
	fclose(stdin);
	fclose(stdout);
	return 0;
}

以下是神奇的被测程序

//不稳的被测程序
//col.cpp
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1005;
int n, a[maxn];

int main()
{
	freopen("test.in","r",stdin);
	freopen("solans.out","w",stdout);
	cin >> n;
	for(int i=1; i<=n; ++i) {
		scanf("%d", &a[i]);
		a[i] += a[i-1];
	}
	int m; cin >> m; while(m--) {
		int x, y; scanf("%d%d", &x,&y);
		cout << a[y] - a[x-1] << '\n';
	}
	fclose(stdin);
	fclose(stdout);
	return 0;
}

文件位置展示
文件位置展示


对拍效果展示
对拍效果展示


最后的总结

  • 在本文中, 多次强调了 可能很稳的暴力程序一词, 这里再次强调。
  • there有各种随机数据的生成模板以及Windows下的对拍程序, 十分值得参考

猜你喜欢

转载自www.cnblogs.com/tztqwq/p/12771394.html