- 分享
全自动对拍
- 2023-6-2 20:53:33 @
大家都知道,有些题目只有测试样例。
大家又都知道,有些题目有人打表。
大家㕛都知道,出数据很难。
大家叒都知道,防止打表更难。
大家叕不知道,有一种技术叫做全自动对拍可以解决这个问题。
全自动对拍:
顾名思义,所有输入数据均为符合格式的随机数,评测程序(std
)和你的程序输出的结果一致就AC
,否则WA
。
示范例子:http://43.139.175.183/p/16
我将展示我是如何出这道题的对拍的:
首先,某些人打表,我受不了,准备加上全自动对拍。
接着,要先写出STD
标准代码:
#include <iostream>
#include <cmath>
using namespace std;
bool a[1001][1001];
int main(){
int x,y;
cin >> x >> y;
int n;
cin >> n;
int cnt = 0;
for (int i = 1;i<=n;i++){
int tx,ty;cin >> tx >> ty;
for (int j = -4;j<=4;j++){
for (int k = -4;k<=4;k++){//偏移量
if (tx+j<=0||ty+k<=0||tx+j>x||ty+k>y) continue;
if (abs(j)+abs(k)<=4&&a[j+tx][k+ty]==false){//判断是否能被灌溉到
cnt++;
a[tx+j][ty+k]=true;
//cout << tx+j << " " << ty+k << endl;
}
}
}
}
cout << cnt;
return 0;
}
接着就是写一段数据生成和对拍器:
先写个随机数:
#include "testlib.h"
#include <iostream>
using namespace std;
int main(int argc, char* argv[]) {
setName("Interactor watering");
registerInteraction(argc, argv);
// //自动生成两个随机整数
rnd.setSeed(time(NULL));
int x = rnd.next(1000);
int y = rnd.next(1000);
int n = rnd.next(1000);
cout << x << " " << y << endl << n << endl;
int cnt = 0;
for (int i = 1;i<=n;i++){
int tx=rnd.next(1000);
int ty=rnd.next(1000);
cout << tx << " " << ty << endl;
}
cout << endl;
}
这里解释一下最后输出endl
的意义:因为testlib
的输入输出不会自动刷新缓冲区,所以我们要输出一个endl
手动刷新。(cout << flush();
好像也可以)(当时被这个问题困惑了老半天,想了半天觉得是缓冲区的锅,然后加了endl
就好了)
接着加上生成标准答案的部分:
#include "testlib.h"
#include <iostream>
using namespace std;
bool a[1001][1001];
int main(int argc, char* argv[]) {
setName("Interactor watering");
registerInteraction(argc, argv);
// //自动生成两个随机整数
rnd.setSeed(time(NULL));
int x = rnd.next(1000);
int y = rnd.next(1000);
int n = rnd.next(1000);
cout << x << " " << y << endl << n << endl;
int cnt = 0;
for (int i = 1;i<=n;i++){
int tx=rnd.next(1000);
int ty=rnd.next(1000);
cout << tx << " " << ty << endl;
for (int j = -4;j<=4;j++){
for (int k = -4;k<=4;k++){
if (tx+j<=0||ty+k<=0||tx+j>x||ty+k>y) continue;
if (abs(j)+abs(k)<=4&&a[j+tx][k+ty]==false){
cnt++;
a[tx+j][ty+k]=true;
}
}
}
}
cout << endl;
int ans;
cin >> ans;
}
加上比较:
#include "testlib.h"
#include <iostream>
using namespace std;
bool a[1001][1001];
int main(int argc, char* argv[]) {
setName("Interactor watering");
registerInteraction(argc, argv);
// //自动生成两个随机整数
rnd.setSeed(time(NULL));
int x = rnd.next(1000);
int y = rnd.next(1000);
int n = rnd.next(1000);
cout << x << " " << y << endl << n << endl;
int cnt = 0;
for (int i = 1;i<=n;i++){
int tx=rnd.next(1000);
int ty=rnd.next(1000);
cout << tx << " " << ty << endl;
for (int j = -4;j<=4;j++){
for (int k = -4;k<=4;k++){
if (tx+j<=0||ty+k<=0||tx+j>x||ty+k>y) continue;
if (abs(j)+abs(k)<=4&&a[j+tx][k+ty]==false){
cnt++;
a[tx+j][ty+k]=true;
}
}
}
}
cout << endl;
int ans;
cin >> ans;
if (cnt != ans)
quitf(_wa, "你这个测试点没过,试试样例能不能过吧!",n,x,y);
else
quitf(_ok, "这个测试点过了!",n,x,y);
}
就成功解决了对拍程序(一般叫做checker.cc
)
最后是config
文件填写:
(照着抄就行了。。。)
type: interactive
interactor: checker.cc
subtasks:
- score: 100
type: sum
cases:
- input: /dev/null
output: /dev/null
- input: /dev/null
output: /dev/null
- input: /dev/null
output: /dev/null
解释一下每一行:
类型:自动对拍
对拍程序:checker.cc
数据点:
-分值100的:
求分方式:求和
数据:
-输入:没有输入文件,对拍程序自动生成
输出:没有输出文件,对拍程序自动生成
-输入:没有输入文件,对拍程序自动生成
输出:没有输出文件,对拍程序自动生成
-输入:没有输入文件,对拍程序自动生成
输出:没有输出文件,对拍程序自动生成
#输入输出有n组就代表有n个测试点
目前有个随机数的bug,就是testlib
的随机数每次测试都一样,站长近期将进入其他随机生成器解决
Update:
新版随机数生成器需要的头文件:
#include <random>
新版随机数初始化:
random_device rd;
mt19937 myrand(rd());
uniform_int_distribution<> u(1, 1000);//括号内的数是随机数的范围,例如1-114514就是uniform_int_distribution<> u(1, 114514);
新版随机数使用:
u(myrand)
//返回一个int类型的随机数,范围在为初始化时的范围
新版对拍程序:
#include "testlib.h"
#include <iostream>
#include <random>
using namespace std;
bool a[1001][1001];
int main(int argc, char* argv[]) {
setName("Interactor watering BETA");
registerInteraction(argc, argv);
random_device rd;
mt19937 myrand(rd());
uniform_int_distribution<> u(1, 1000);
int cnt = 0;
int x = u(myrand);
int y = u(myrand);
int n = u(myrand);
cout << x << " " << y << endl << n << endl;
cnt = 0;
for (int i = 1;i<=n;i++){
int tx=u(myrand);
int ty=u(myrand);
cout << tx << " " << ty << endl;
for (int j = -4;j<=4;j++){
for (int k = -4;k<=4;k++){
if (tx+j<=0||ty+k<=0||tx+j>x||ty+k>y) continue;
if (abs(j)+abs(k)<=4&&a[j+tx][k+ty]==false){
cnt++;
a[tx+j][ty+k]=true;
}
}
}
}
cout << endl;
int ans;
cin >> ans;
if (cnt != ans)
quitf(_wa, "你这个测试点没过,试试样例能不能过吧!");
else
quitf(_ok, "这个测试点过了!调试信息:n=%d x=%d y=%d",n,x,y);
}
2 条评论
-
bpoj.top (Black-Panda) @ 2023-6-2 21:25:08
bpoj有全自动对拍,用
mt19937
就可以。 -
2023-6-2 20:59:00@
我看不懂...
- 1