在算法競賽中,我們常常會遇到一道題一直WA的情況,這時我們不得不自己造樣例,這會耗費大量時間,而且還不一定能快速確定樣例的答案。所以,如果時間充足,可以寫一個對拍程序。
對拍程序需要四個文件:
1.我們已經寫好但WA的待測試文件,記為code.cpp
2.一個純暴力程序(復雜度高但能保證答案一定正確),記為std.cpp
3.一個數據生成器(用srand函數和rand函數產生隨機數即可),記為data.cpp
4.一個用于比較輸出的shell腳本,記為duipai.sh
對拍程序,顧名思義,就是隨機生成數據給兩個程序分別跑一遍,看看對不對的上。
我們以一個計算1到n的和的程序為例,我們都知道計算1到n的暴力方法是用循環(huán)加和,簡便方法則是使用等差數列求和公式。
下面是待測試程序code.cpp(等比數列求和,當然這里沒有WA)
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
cin>>n;
cout<<n * (n + 1) / 2<<endl;
return 0;
}
下面是暴力求和程序std.cpp
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
cin>>n;
int ans = 0;
for(int i = 1;i <= n;i++){
ans += i;
}
cout<<ans<<endl;
return 0;
}
然后是隨機數據生成器data.cpp
#include<bits/stdc++.h>
using namespace std;
int main(){
srand(time(0));
int n = 100;
while(n--){
int k = rand() % 10 + 1; //生成100個[1,10]的隨機數
cout<<k<<endl;
}
return 0;
}
rand函數和srand函數的用法有點忘了,參見:有關rand(),srand()產生隨機數學習總結
最后是duipai.sh
#!/bin/bash
while true; do
./data > data.in
./std <data.in >std.out
./code <data.in >code.out
if diff std.out code.out; then
printf "AC\n"
else
printf "Wa\n"
exit 0
fi
done
這個程序的意思是運行三個可執(zhí)行文件,比較std.out code.out是否相同,相同輸出"AC",不相同輸出錯誤信息,并輸出"WA"且退出。
下面開始跑對拍,先用g++編譯三個cpp文件,g++ code.cpp -o code
,g++ std.cpp -o std
,g++ data.cpp -o data
。g++ code.cpp -o code
表示將code.cpp編譯并連接生成一個名為code的可執(zhí)行文件,如果不加 -o 選項,所有cpp文件都默認生成一個名為a.out的可執(zhí)行文件。通過./a.out
可以運行這個可執(zhí)行文件,./
表示當前目錄。如果加上 -c 選項,如g++ -c code.cpp -o code
則只編譯不連接,會產生一個obj文件而不是exe文件。
編譯完成后,輸入sh duipai.sh
即得結果。