以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;
}