C++對拍
文章目錄
前言
近期考古發現,本人於2017年3月水了一篇對拍。 我發現它實在是水,估計沒多少人看得懂。 作為一個內心善良,樂於助人,無比有愛心的人。
我決定再水一篇對拍。
本文廢話較多,程式碼較噁心,諸君可以跳躍性閱讀。
對拍
解釋
根據百度漢語對“拍”的解釋,好像無法理解這個詞。 簡單來說,就是寫一個數據生成器,然後把生成的資料給兩個不同的程式執行,比較它們輸出的結果。 主要有兩個用途:
- 比賽(考試)時,寫了一個自以為正確的程式,但是還是不放心,可以再寫一個暴力程式,對拍驗證。
- 做題做到天昏地暗,頭暈目眩,不分東南西北之時,眼前一片血紅,於是不小心偷了一個充滿生命力的程式碼,再寫個資料生成器,說不定對拍能挽救程式碼的生命。
例題
A+B Problem
資料生成器
方法
生成隨機數之必備武器:ctime
、cstdlib
。
在main
開頭寫:
srand((unsigned)time(NULL));
意思大概是設定隨機數的種子為你的時間。
如果你不寫或者寫個srand(1234567)
,你發現你每次生成的“隨機數”都是一樣的。
然後使用:
int x=rand();
就可以得到一個到不知道多少(RAND_MAX
)的整數。
如果你想得到得到之間的一個整數:
int x=rand()%(b-a+1)+a;
如果有些大,可以這樣,以防資料太弱:
int x=1ll *rand()*rand()%(b-a+1)+a;
如果想得到浮點數,除以即可。
當然,如果想要生成一個樹、一個連通圖、一個二分圖什麼的,加點資料結構之類的就行了 。
曾經我為了對拍一個破圈法的題,寫了100多行的資料生成器。
程式碼
#include<ctime>
#include<cstdio>
#include<cstdlib>
#define MAXN 1000
int main(){
srand((unsigned)time(NULL));
int A,B;
A=rand()%MAXN;
B=rand()%MAXN;
printf("%d %d\n",A,B);
//想像一下用手輸資料的時候不打換行會怎麼樣,這裡就會怎麼樣
}
你的程式 == WA
什麼都不用加,找的你的程式的exe
檔案即可。
#include<cstdio>
int main(){
int a,b;
scanf("%d%d",&a,&b);
printf("%d",a/b*b+b);
}
我的程式 == AC
什麼都不用加,偷到我的程式的exe
檔案即可。
沒有時間了,只好先水一個SPFA
,如有錯請見諒 。
#include<queue>
#include<cstdio>
#include<cstring>
using namespace std;
#define MAXM 2
#define MAXN 3
struct Edge{
int v,w;
Edge *Next;
}E[MAXM+5];
Edge *ecnt,*First[MAXN+5];
void Init(){
ecnt=&E[0];
memset(First,0,sizeof First);
}
void AddEdge(int u,int v,int w){
++ecnt;
ecnt->v=v,ecnt->w=w;
ecnt->Next=First[u],First[u]=ecnt;
}
int dist[MAXN+5];
bool vis[MAXN+5];
int SPFA(int S,int T){
memset(vis,0,sizeof vis);
memset(dist,0x3f,sizeof dist);
queue<int> Q;Q.push(S);
dist[S]=0,vis[S]=1;
while(!Q.empty()){
int u=Q.front();
Q.pop();vis[u]=0;
for(Edge *i=First[u];i!=NULL;i=i->Next){
int v=i->v,w=i->w;
if(dist[v]>dist[u]+w){
dist[v]=dist[u]+w;
if(!vis[v]){
vis[v]=1;
Q.push(v);
}
}
}
}
return dist[T]==0x3f3f3f3f?-1:dist[T];
}
int main(){
int a,b;
scanf("%d%d",&a,&b);
Init();
AddEdge(1,2,a);
AddEdge(2,3,b);
printf("%d",SPFA(1,3));
}
AC
證明:
對拍程式
其實我的續集只是續的這個部分。
古文《對拍》中,是使用的C++
寫對拍,各位是不是感覺很慢?看上去很不爽?還要編譯?
所以現在使用bat
檔案完成對拍,Windows下有一個命令:fc
,可以比較兩個檔案。
準備活動
方法:
- 在一個你喜歡的位置新建一個記事本檔案
dp.txt
- 將字尾
.txt
改成.bat
,所以你的檔案變成了dp.bat
這個時候問題來了: 我的檔案是這樣的嚶嚶嚶: 這樣做: 隨意開啟一個資料夾(左上角)組織資料夾和搜尋選項(上方)檢視下面的高階設定中找到“隱藏已知檔案型別的副檔名”,把前面的勾去掉即可。
然後你就會發現變成了這樣:
把.txt
改成.bat
:
程式碼
繼續:
- 右鍵
dp.bat
,點選“編輯”
接下來才是重點。 仔細觀察你即將貼上進去的程式碼:
@echo off
:loop
資料生成器位置 > data.txt
你的程式的位置 < data.txt > yours.txt
我的程式的位置 < data.txt > mine.txt
fc yours.txt mine.txt
if not errorlevel 1 goto loop
pause
goto loop
你急用就直接粘過去,如果你希望考試的時候能用就繼續看。
示例
@echo off
:loop
C:\3\bin\Debug\3.exe > data.txt
C:\1\bin\Debug\1.exe < data.txt > yours.txt
C:\2\bin\Debug\2.exe < data.txt > mine.txt
fc yours.txt mine.txt
if not errorlevel 1 goto loop
pause
goto loop
注意一定要填exe
檔案。
把上面的程式碼儲存後,直接雙擊dp.bat
。
你一定看懂了它的意思。
這時開啟data.txt
,裡面是你的資料生成器生成的資料,yours.txt
和mine.txt
分別是你的輸出結果和我的輸出結果。
當然,你可以“按任意鍵繼續”。 如果輸出一樣是什麼效果請自行試驗。
更多內容
這裡個人是對對拍程式碼的解讀,更準確的內容請百度。
@echo off
:此句可不要,但會多輸出一些提示性語句。echo
有回聲的意思,應該是指回顯,而off
就是關閉。至於為什麼fc
的回顯沒有關閉,不知道= =:loop
和goto loop
:等於C++
的loop:
和goto loop
,相當於迴圈。<
和>
:大概是執行後輸入輸出之意。fc FILE1 FILE2
:比較FILE1
和FILE2
。if not errorlevel 1
:大概是看fc
的“返回值”,判斷兩檔案是否相同。pause
:按任意鍵繼續
以上語句全部可以通過C++
的system
函式執行,效果相同。
後記
感謝你閱讀到了這裡(可能你是一下子拉到底的),本文確實廢話較多,但是之前的《對拍》有些內容確實不太優秀,我又不忍心刪掉它,所以寫了這樣一篇。