关于Linux环境下的对拍
关于Linux环境下的对拍
前言
- 在OI竞赛中,日常训练Debug以及考场上验证正解的正确性,我们经常将自己的
Bug代码和同学的正确性未知的代码做人眼比对,咳咳,当然不,还是要用电脑做对拍,效率更高,查错更快。
Method
- 显然,我们需要四组代码,一个亟待Debug的代码,一组正确代码,一组随机数生成器(后续),以及对拍程序。
- 以信息竞赛经典算法——排序(据说可能面试要用?)为例,我们用到sort和冒泡排序,详情见代码块。
- std.cpp
int main(){ freopen("std.out", "w", stdout); cin >> n; for(int i = 1; i <= n; i++) cin >> a[i]; sort(a + 1, a + 1 + n);//stable_sort同理 for(int i = 1; i <= n; i++) cout << a[i] << " "; return 0; }
- tmp.cpp
int main(){ freopen("tmp.out", "w", stdout); cin >> n; for(int i = 1; i <= n; i++) cin >> a[i]; for(int i = 1; i <= n; i++) for(int j = i + 1; j <= n; j++) if(a[i] > a[j]) swap(a[i], a[j]); for(int i = 1; i <= n ;i++) cout << a[i] << " "; return 0; }
- rand.cpp
关于数据生成,每道题需要的数据不一样,#include <iostream> #include <ctime>//rand函数需要 #include <algorithm> using namespace std; int main(){ freopen("rand.out", "w", stdout); srand(time(NULL)); int n = rand() % 10 + 1; cout << n << endl; while(n--){ int a = rand() % 100 + 1; cout << a << " "; } cout << endl; }
- dp.cpp
由于要进行大量的比对操作,所以选择使用文件对比,否则就失去了对拍的意义
上述代码运行时,运行了文件对比函数diff,当两个文件不完全一致时,返回结果true,此时输出“WA”且程序停止运行,将hack数据保存在rand.out中,以便手模查错。#include <algorithm> using namespace std; int main(){ int T = 10000; int tot = 0; while(T--){ tot++; cout << tot << " "; system("./rand; ./std; ./tmp"); if(system("diff std.out tmp.out")){ cout << "WA" << endl; return 0; } else cout << "AC" << endl; } }
后续——浅析rand随机数生成函数
- 这里的数据生成程序是调用的外部程序, 每个数据点都重新运行, 而在linux系统上, time(0)会返回当前时间戳, 即从1970年1月1日0点0分0秒到现在经过的秒数, 所以每秒time(0)的返回值不变, 作为随机数种子时, 每秒内生成的数据也都相同, 那么该怎么修改呢?
- 首先我们要知道linux系统上一个特殊的设备/dev/urandom, 它提供永不为空的随机二进制数据流, 当然还有更随机的/dev/random。但是/dev/random为了保证随机性可能会中断输出, 相比之下, /dev/urandom不会导致程序堵塞。
- 更多信息参见内核熵池
实际应用时, 把/dev/urandom当作一个文件, 使用freopen读入
freopen("/dev/urandom", "r", stdin);
然后初始化随机数种子时, 使用getchar()读入:
srand(getchar()*getchar()*getchar()*time(0));
11.23UPD
\(Shell\)
make data
make 001
make 002
((cnt=1))
while true
do
./data > in
./001 < in > 1.out
./002 < in > 2.out
if diff 1.out 2.out; then
printf "# $((cnt++)) Accepted\n";
else
notify-send "Gary"
break
fi
done
风吹过,我来过~