以2019杭電多校的一道題爲例。
題目傳送門
將正確程序還有WA的程序放在同一目錄下(這兩個程序按照一般寫法即可),然後再寫個樣例隨機生成代碼。然後代碼都要編譯一下,生成對應的exe文件,因爲對拍程序調用的是exe文件,所以源代碼改了,還要重新編譯一下,更新exe文件。然後新建txt,寫入一下代碼。然後將文件後綴改爲.bat,一切就緒後就可以雙擊.bat文件,windows會調用cmd窗口,顯示運行結果。
如果文件不再同一目錄,只要在文件前面加上盤符/等信息(絕對路徑),自行谷歌。
對拍核心代碼:
:again
test > input.txt
permutation1 < input.txt > test_output.txt
permutation2n < input.txt > rt_output.txt
fc /N test_output.txt rt_output.txt
if not errorlevel 1 goto again
pause
代碼解釋:
代碼第一行類似於定義一個函數。
第二行,可以類比c++中的輸入輸出流,就是講test.exe運行出來的結果寫入input.txt文件,這就類似輸出流。
第三行的<類似於輸入流,也就是將input.txt文件的數據讀入permutation程序中作爲輸入數據。
第四行,調用windows比較函數fc, /N是這個函數的參數。自己可以上網查閱。
其他的就沒什麼注意得了。
樣例隨機生成代碼:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <fstream>
#include <algorithm>
#include <windows.h>
using namespace std;
int fac(int x){
int res = 1;
for(int i = 2;i <= x;++i){
res *= i;
if(res > 1e4){
return res;
}
}
return res;
}
int main(){
// freopen("food.in","w",stdout);
// srand((unsigned)time(NULL));
srand(time(0));
int T = 0,n = 0,k = 0;
int nT = 40,nn = 20,kk = 10000;
T = rand() % nT + 1;
printf("%d\n",T);
while(T--){
n = rand() % nn + 1;
k = rand() % min(kk,fac(n)) + 1;
printf("%d %d\n",n,k);
}
return 0;
}
AC代碼:
#include<bits/stdc++.h>
#define per(i,a,b) for(int i = (a);i <= (b);++i)
#define rep(i,a,b) for(int i = (a);i >= (b);--i)
using namespace std;
const int maxn = 20 + 10;
int n = 0,k = 0,cnt = 0;
int ans[maxn];
bool vis[maxn];
void init(){
cnt = 0;
per(i,1,n){
vis[i] = false;
}
}
bool dfs(int depth,int minv,int maxv){
if(depth > n){
++cnt;
if(cnt == k){
per(i,1,n){
printf("%d%c",ans[i] - minv + 1,i == n ? '\n' : ' ');
}
return true;//如果找到了答案就停止dfs
}
return false;//否則繼續尋找
}
per(i,maxv - (n-1),minv + (n-1)){
if(vis[i]){
continue;
}
ans[depth] = i;
vis[i] = true;
if(dfs(depth+1,min(minv,i),max(maxv,i))){
vis[i] = false;
return true;//如果找到了答案就停止dfs,退出循環,不在dfs該節點的其他子樹
}
vis[i] = false;
}
return false;
}
int main(){
int T = 0;
scanf("%d",&T);
while(T--){
scanf("%d %d",&n,&k);
init();
ans[1] = n;
vis[ans[1]] = true;
dfs(2,n,n);
}
return 0;
}
WA的代碼:
#include<bits/stdc++.h>
#define per(i,a,b) for(int i = (a);i <= (b);++i)
#define rep(i,a,b) for(int i = (a);i >= (b);--i)
using namespace std;
typedef long long LL;
#define INF 1e9
const int maxn = 30;
int n = 0,k = 0;
vector<int> ans;
bool vis[maxn];
int fac(int x){
int res = 1;
per(i,2,x){
res *= i;
if(res > 1e4){
break;
}
}
return res;
}
void init(){
ans.clear();
per(i,1,n){
vis[i] = false;
}
}
void solve(){
int num = fac(n-1);
ans.push_back(0);
ans[0] = n+1 - ceil(k*1.0/num);
vis[ans[0]] = true;
if(k % num == 0){
k = num;
}else{
k %= num;
}
rep(i,n-2,1){
num = fac(i);
int pos = ceil(k*1.0/num);
int cnt = 0,las = -1;
bool fg = true;
per(i,1,n){
if(!vis[i]){
++cnt;
las = i;
if(cnt == pos){
ans.push_back(i);
fg = false;
vis[i] = true;
break;
}
}
}
if(fg){
ans.push_back(las);
vis[las] = true;
}
if(k % num == 0){
k = num;
}else{
k %= num;
}
}
per(i,1,n){
if(!vis[i]){
ans.push_back(i);
break;
}
}
per(i,0,n-1){
printf("%d%c",ans[i],i == n-1 ? '\n' : ' ');
}
// printf("fnadsuiofhasofiaj\n");
}
int main(){
// freopen("food.in","r",stdin);
// freopen("food.out","w",stdout);
int T = 0;
scanf("%d",&T);
while(T--){
scanf("%d %d",&n,&k);
init();
solve();
}
return 0;
}