对拍:本地随机数据评测系统 LRDTS
对拍:本地随机数据评测系统 LRDTS
在OI
或者是ACM
竞赛中,代码的提交只能有\(1\)次机会,或者每一次提交错误都会增加罚时,使得成绩被影响。
竞赛中题目通常会有小样例,但其数据强度无法保证,你不一定能通过测试这些样例来让程序bug free。
因此,如何在计算机本地生成海量数据,并测试待提交程序的正确性就是亟需解决的问题。
现在以下面一个题目为例,我们来讨论这种方法。
a+b Problem
现在有\(a,b\)两个非负整数,请输出\(a+b\)的值。
对于\(100\%\)的数据满足\(0 \leq a,b\leq 10^{1000}\)
上述问题,可以用高精度来解决,时间复杂度为\(O(lga + lg b)\)
// sol.cpp
# include <bits/stdc++.h>
using namespace std;
const int MAX=1e3+10;
int main(void) {
char str[MAX];
int arr1[MAX]={0},arr2[MAX]={0},len,len1,len2,i,j;
scanf("%s",str);
len1=strlen(str);
for(i=0;i<len1;i++)
arr1[i]=str[len1-1-i]-'0';
scanf("%s",str);
len2=strlen(str);
for(i=0;i<len2;i++)
arr2[i]=str[len2-1-i]-'0';
len=(len1>len2)?len1:len2;
for(i=0;i<len;i++)
{
arr1[i+1]+=j=(arr1[i]+arr2[i])/10;
arr1[i]=(arr1[i]+arr2[i])%10;
}
if(j)len++;
for(i=0;i<len;i++)
printf("%d",arr1[len-1-i]);
return 0;
}
当然,在数据范围较小的情况下,下面的简单程序也可以实现相关功能。
// std.cpp
# include <bits/stdc++.h>
using namespace std;
int main() {
int a,b; scanf("%d%d",&a,&b);
printf("%d\n",a+b);
return 0;
}
为了生成一组随机数据,我们还需要一个自动生成数据的程序,需要保证每次生成的数据都是不同的。
// maker.cpp
# include <bits/stdc++.h>
using namespace std;
int main()
{
srand(time(NULL)*10007);
printf("%d %d\n",rand(),rand());
return 0;
}
其中srand(time(NULL)*10007);
代码是让随机种子按照时间变化,这可以保证每次生成的数据都是不同的。
请注意,现在将三个cpp
文件放在同一个子目录内,并编译生成对应exe
文件,等待调用。
若修改cpp
文件,也需要重新编译生成对应exe
文件,请时刻保证exe
文件和cpp
文件的对应关系。
接下来,我们需要一个程序,按照如下顺序执行:
- 执行
maker.exe
生成输入数据a.in
- 输入数据
a.in
到std.exe
生成标准答案std.out
- 输入数据
a.in
到sol.exe
生成待检测答案sol.out
- 比较
std.out
和sol.out
,若完全相同则重新执行上述操作,否则跳出循环以提示。
这个简单的程序,可以用系统自带的bat
文件实现:
:loop
maker > a.in
std < a.in > std.out
sol < a.in > sol.out
fc std.out sol.out
if not errorlevel 1 goto loop
我们可以先用记事本编写上述代码dp.txt
,并将其后缀名改为.bat
放在相同目录下。
如图所示,下面是一个正确的子结构:
-----| 对拍
------------| std.cpp std.exe
------------| sol.cpp sol.exe
------------| maker.cpp maker.exe
------------| dp.bat
需要对拍时,双击打开dp.bat
文件即可。
一定时间内,dp.bat
仍在运行,说明您的解答正确性较高,否则您的答案有wa
的风险,一个错误数据在a.in
中
需要说明的是:在本地通过对拍的程序,也有可能在提交评测的时候得到wa
的结果,因此本地评测只能作为参考