对拍Bete
前言
那天LZY需要对拍,题目样例给的是一个图,LZY发现自己的对拍程序并不能生成图。
这时候msjing站出来说:
我有随机生成图的程序。
这么好?
于是我直接拿来用。
用着用着不对劲。
- 你这图生成的什么玩意?
- msjing不知道
靠别人不如靠自己,在我坚持了3.1415926个小时后,终于写成了一个较为强大的随机样例生成器,大部分常用生成器均已打包进了函数里。
完整对拍程序
下载
注意:这个有亿点锅。
| 版本(胡扯) | 系统 | 语言 | 大小 | 下载 | 备注 |
|---|---|---|---|---|---|
| 2.0(开源) | Windows | C++14及以上 | 1.35 MB | 对拍2.0(开源).zip | 这个纯粹是因为没有教程而发的 |
| 2.0(用户版) | Windows | C++14及以上 | 1.34MB | 对拍2.0(用户版).zip | 教程正在筹备,有能力的可以下载开源版自己摸索 |
| 以下版本有适配性问题 | 以下版本下载链接失效 | 这个锅我到现在才意识到 | |||
| 1.2.0(测试) | Windows | C++14及以上 | 1.18 MB | 对拍1.2.0(测试).zip | 可以下载 |
| 1.1.5(测试) | Windows | C++14及以上 | 907.15 KB | 对拍1.1.5(测试).zip | 跟前一个版本没什么变化 |
| 1.1.4(正式) | Windows | C++14及以上 | 907.08 KB | 对拍1.1.4(正式).zip | 稳定,可以下载 |
| 1.1.3(正式) | Windows | C++14及以上 | 903.25 KB | 对拍1.1.3(正式).zip | 跟后一个版本没什么变化 |
| 1.1.2(测试) | Windows | C++14 | 904.55 KB | 对拍1.1.2(测试).zip | 锅最多的版本 |
| 1.1.1(正式) | Windows | C++14 | 903.12 KB | 对拍1.1.1正式版.zip | 老,啥也没有 |
有人跟我犟,说我就要用1.2.0及以前的版本。
其实源文件并没有删,把链接复制过来,在在里面加上“对拍”两个字,就可以下了。
错误链接:
https://files.cnblogs.com/files/blogs/870368/1.2.0(测试).zip?t=1786588525&download=false
正确链接:
https://files.cnblogs.com/files/blogs/870368/对拍1.2.0(测试).zip?t=1786588526&download=true
然后发现这个东西出了作者在的机房电脑可以用,其他电脑上的那个快捷方式都是假的,只能去文件夹里把原文见打开。
在2.0以及后续版本不会出现这种问题(应该),可以放心使用。
另外,开源版本设有密码,可以打开源文件自行查找,也是作者给的一个小小考验qwq。
使用教程[以2.0(用户版)为准]
-
首先最重要的一步是,你要把它下下来。
-
然后暴力解压,到哪去都行。
-
打开那个“对拍-用户版”文件夹,可以看到一个“启动!.bat”文件,双击运行它(不保证不同电脑中文显示不会出现乱码的情况)。
-
然后一个黑框框一闪而过然后打开了另一个黑框框,你就可以在上面输入指令运行了。
下面说一下每一个指令及作用
-
start
这是开始对拍的指令。
输入 “start <num>” 后,程序会进行 <num> 次对拍。 -
close
这个是用来停用一些功能的。
具体什么功能?- “G” 可以停用 “Generator”。
- “A” 可以停用 答案程序。
- “U” 可以停用 用户程序。
- “all” 可以停用上面三个。
- “auto” 可以停用 自动编译。
输入“close <option>”即可使用。
-
need
这个跟上面相反,是用来启用一些功能的。
用法一样,选项一样。输入“need <option>”即可使用。
-
open
不要整错了,这个是用来打开文件夹的。- “G” 可以打开 “Generator” 文件夹。
- “A” 可以打开 答案程序 文件夹。
- “U” 可以打开 用户程序 文件夹。
- “C” 可以打开 “Checker” 文件夹。
- “all” 可以打开上面四个。
- “P” 可以打开 “program” 文件夹。
- “WA” 可以打开 “WA-input” 文件夹。
每个文件夹作用在后面会说的,不要着急。
输入 “open <option>” 即可使用。
-
show
用于查看当前的配置信息。- “name” 可以查看 程序名称及输入输出文件名 。
- “path” 可以查看 程序相对路径。
- “need” 可以查看 启用/停用 情况。
- “compile” 可以查看 编译指令。
输入 “show <option>” 即可使用。
-
change
要是只能看不能改哪还有什么意思?输入 “change”+回车 按照指示写就行(其实所有指令都有指示)。
-
save
费好大劲整完了一不小心关掉了然后就要重新配置,因为作者懒所以出了个保存功能。
输入 “save <plan name>” 即可将当前的配置保存到 “<path name>” 中。 -
apply
是上一个的孪生兄弟,用于应用已经保存好的方案。
输入 “apply <plan name>” 即可应用 “<path name>” 配置。 -
命令行
另外,如果你输入的指令是上面没有的话,程序会让命令行去运行。
比如你输入了一个 “cls”,会清空屏幕。
-
使用 “open” 指令分别打开 “A”、“U”,然后你可一进行一下任意一种操作:
- 将代码粘到事先准备好的 “.cpp” 文件中。
- 将代码文件扔到那个文件夹里。
- 或者简单粗暴,直接将编译好的 “.exe” 文件扔进去。
-
使用 “open” 打开 “G” 在 “Generator.cpp” 里面生成数据。
-
若有 “Special Judge” ,使用 “open” 打开 “C”,然后你可一进行一下任意一种操作:
- 在 “Checker.cpp” 中自己写一个 “Special Judge”。
- 直接上传一个 “.exe” 文件,程序会按照 “<checker name>.exe <input> <user's output> <answer ouput>” 的方式运行。
-
然后使用 “change” 指令调整配置,程序名一定不能加后缀,文件名后缀可加可不加,但一定要与你程序的输入输出文件一致。
-
最后就可以用 “start” 指令开始对拍。
-
当出现非WA结果时,这个对拍不会像其他对拍那样直接停掉,而是会将错误测试点输入样例同意放到 “WA-input” 文件夹中,使用 “open WA” 即可打开。
-
出现RE结果应该会直接停掉,在测试的时候并没有出现RE报错,我也忘了我自己写的什么了qwq;
随机样例生成器
随机样例生成器
#include<bits/stdc++.h>
#include<tuple>
#include<vector>
#define uint unsigned int
#define ll long long
#define ull unsigned long long
#define dbl double
#define TIME chrono::system_clock::now().time_since_epoch().count()
using namespace std;
mt19937_64 num(TIME);
template<typename T>inline T INT(T l,T r,char out=0){T x=num()%(r-l+1)+l;if(out)cout<<x<<out;return x;}
template<typename T>inline vector<T> INT(int len,T l,T r,char out=0,char out2=0){vector<T> v(len);for(int i=0;i<len;++i) v[i]=INT(l,r,out);if(out2) cout<<out2;return v;}
template<typename T>inline T FLO(T l,T r,char out=0,int pos=3){
uniform_real_distribution<long double> flo(l,r);
T x=flo(num);
if(out) cout<<fixed<<setprecision(pos)<<x<<out;
return x;
}
template<typename T>inline vector<T> FLO(int len,T l,T r,char out=0,char out2=0,int pos=3){
vector<T> v(len);
for(int i=0;i<len;++i) v[i]=FLO(l,r,out,pos);
if(out2) cout<<out2;
return v;
}
inline char CH(char l,char r,char out=0){char x=num()%(r-l+1)+l;if(out)cout<<x<<out;return x;}
inline char CH(string s,char out=0){char x=s[INT(0,(int)s.size()-1)];if(out)cout<<x<<out;return x;}
inline string STR(int len,char l,char r,char out=0,char out2=0){string s;for(int i=1;i<=len;++i) s+=CH(l,r,out);if(out2) cout<<out2;return s;}
template<typename T> inline T Pick(initializer_list<T> s,char out=0){
T x=*(s.begin()+num()%s.size());
if(out) cout<<x<<out;
return x;
}
template<typename T>inline vector<T> Pick(int len,initializer_list<T> s,char out=0,char out2=0){
vector<T> v(len);
for(int i=0;i<len;++i) v[i]=Pick(s,out);
if(out2) cout<<out2;
return v;
}
pair<int,int> ITV(int l,int r,char out=0){
int x=INT(l,r),y=INT(l,r);
if(x>y) swap(x,y);
if(out) cout<<x<<' '<<y<<out;
return {x,y};
}
auto Graph(int point,int edge,int weightl=0,int weightr=0,vector<string> t={}){
map<string,bool> type;
for(string s:t) type[s]=1;
bool repeat=type["repeat"],directed=type["directed"],
forest=type["forest"],self=type["self"],
heap=type["max-heap"]|type["min-heap"]|type["heap"];
vector<tuple<int,int,int> > g;
map<pair<int,int>,bool> vis;
vector<int> tmp;
if(type["max-heap"]) for(int i=point;i>=1;--i) tmp.emplace_back(i);
else for(int i=1;i<=point;++i) tmp.emplace_back(i);
if(!heap) shuffle(tmp.begin(),tmp.end(),num);
if(!forest)
for(int i=1,x,y;i<(int)tmp.size();++i){
x=tmp[INT(0,i-1)],y=tmp[i];
if(!repeat){
if(directed)vis[{x,y}]=1;
else vis[{x,y}]=vis[{y,x}]=1;
}
g.emplace_back((tuple<int,int,int>){x,y,INT(weightl,weightr)});
}
if(!forest) edge-=point-1;
if(!type["tree"])
while(edge>0){
int x=INT(1,point),y=INT(1,point);
while(vis[{x,y}]||(x==y&&!self)) x=INT(1,point),y=INT(1,point);
if(!repeat){
if(directed)vis[{x,y}]=1;
else vis[{x,y}]=vis[{y,x}]=1;
}
g.emplace_back((tuple<int,int,int>){x,y,INT(weightl,weightr)});
edge--;
}
if(type["value"]) for(auto x:g)cout<<get<0>(x)<<' '<<get<1>(x)<<' '<<get<2>(x)<<'\n';
else if(type["out"]) for(auto x:g)cout<<get<0>(x)<<' '<<get<1>(x)<<'\n';
return g;
}
void Generate(){
//write here!!!!!!!!!!!!!!!!
}
signed main(int argn,char* argv[]){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
if(argn==2) freopen(argv[1],"w",stdout);
Generate();
return 0;
}
使用教程[以2.0(用户版)为准]
随机生成整数INT()
使用INT()函数可以随机生成整数,返回值类型与传入参数 \(l,r\) 有关。
函数参数:
随机生成整数,返回一个整数。
- \(l,r\) (必要参数)表示生成随机数的范围 \([l,r]\)。
- \(out\) (非必要参数)表示是否输出及输出类型,默认为 \(0\),即不输出,若传入「空格」则表示将生成的随机数输出并输出后输出「空格」。
生成随机整数数列,返回一个vector。
- \(len\) 表示生成随机数列的长度。
- \(l,r\) 同上。
- \(out\) 表示数列中每一个数的输出类型,默认为 \(0\)。
- \(out2\) 表示整个序列的输出类型,默认为 \(0\)。
注意:
为避免传参混乱的问题,请不要写类似 \(INT(int,int,int)\) 的传参。
随机生成浮点数FLO()
使用FLO()函数可以生成随机浮点数,返回值类型与 \(l,r\) 有关。
函数参数:
随机生成浮点数,返回一个浮点数。
- \(l,r,out\) 同上。
- \(pos\) 表示输出时小数的位数。
生成随机浮点数数列,返回一个vector。
- \(len,l,r,out,out2,pos\) 同上。
随机生成字符(串)CH()/STR()
使用CH()函数可以生成一个字符,STR()可以生成一个字符串。
函数传参:
生成一个字符,返回char。
- \(l,r,out\) 同上。
生成一个字符串,返回一个string。
- \(len,l,r,out,out2\) 同上。
随机选择Pick()
使用Pick()可以在一个有限集合内选择元素。
函数传参:
在集合中选择一个元素,返回该元素。
- \(s\) 传入的集合,集合内元素使用花括号{}包裹,逗号分割。
- \(out\) 同上。
多次随机选择元素组成一个元素列,返回一个vector。
- \(len,s,out,out2\) 同上。
随机生成区间ITV()
使用ITV(),随机生成一个区间。
函数传参:
生成 \([l,r]\) 的一个子区间,返回一个pair<int,int>。
- \(l,r\) 区间范围。
- \(out\) 同上。
随机生成图Graph()
使用Graph函数可以快速生成一个图。
完整参数如下。
Graph(int point,int edge,int weightl=0,int weightr=0,vector<string> t={})。
point表示节点数。edge表示边数。weightl与weightr表示权值的范围。
最后的vector<string> t={}表示指令。
tree指令可以让函数强制生成一颗树,只在乎节点数,不在乎边数。forest指令允许函数生成的图不连通,即森林。directed指令会使函数认为\(x \rightarrow y\)与\(y \rightarrow x\)不是一条边,即生成有向图。out指令可以让函数直接将这颗树输出。value指令可以让函数输出时额外输出边权。repate指令可以允许函数生成重边。self指令可以允许函数生成自闭环。heap类命令可以让函数生成的树满足堆性质,默认为小根堆,min-heap、max-heap分别对应小根堆、大根堆。
auto g=Graph(10,10); //生成10个节点10条边的基环树。
auto g=Graph(10,100,1,1000,{"value","repeat","forest"});
//生成一个10个节点100条边、可重边、权值在 1~1000 之间的带边权的无向图,并带权输出,同时将图返回给变量 g。其中允许生成的图不连通。
注意
-
若你不传任何指令,函数默认生成一个不重边、无自闭环的无向联通图,返回值类型为
vector<tuple<int,int,int> >,tuple中的三个元表示 边与权值。 -
此生成随机图函数为不完整版,生成速度较慢,请不要使用它生成规模 \(1e5\) 以上的树,若要生成 \(1e6\) 规模的图请加上
forest和repeat指令。 -
若没有
forest指令,函数会先生成一颗树,再在树的基础上加边,也就是说如果传入的边数小于节点数减一,那么函数将返回一颗树。 -
若没有
repeat指令,传入的边数远远大于节点数的话,函数会四掉的。 -
仍要注意的是无论你是否选择输出,函数都会将图返回。
开源代码
Lancher
#include<bits/stdc++.h>
#include<windows.h>
#include <stdio.h>
#include <dirent.h>
using namespace std;
void color(int c){
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(handle, c);
}
void print(string s,int col){
color(col);
cerr<<s;
color(7);
}
bool isNum(string s){
if(s=="") return 0;
for(char x:s) if(x<'0'||x>'9') return 0;
return 1;
}
void Getline(istream& in,string &s){
char x=in.get();s="";
while(x=='\n') x=in.get();
while(x!='\n') s+=x,x=in.get();
}
void Getline(ifstream& in,string &s){
char x=in.get();s="";
while(x=='\n') x=in.get();
while(x!='\n') s+=x,x=in.get();
}
string test_num="10";
bool auto_compile=1;
string compile="-std=c++14 -o2";
bool need_Generator=1,need_Answer=1,need_User=1;
char need_[]="TTT";
string show_name[10]={
"Generator ",
"User's program",
"Answer progeam",
"Checker ",
"Sample input ",
"User's output ",
"Answer output "
};
string name_[10]={
"Generator",
"User",
"Answer",
"Checker",
"input.in",
"output.out",
"output.ans"
};
string path_[10]={
"program\\generator\\",
"program\\user\\",
"program\\answer\\",
"program\\checker\\",
"..\\..\\"
};
string merge(){
string tmp="Leader.exe "+(string)need_;
for(int i=0;i<7;++i) tmp+=' '+name_[i];
for(int i=0;i<5;++i) tmp+=' '+path_[i];
return tmp+' '+test_num;
}
bool check(){
ifstream G,U,A,C;
G.open(path_[0]+name_[0]+".exe");
U.open(path_[1]+name_[1]+".exe");
A.open(path_[2]+name_[2]+".exe");
C.open(path_[3]+name_[3]+".exe");
bool f=0;
if(!G.is_open()&&need_[0]=='T'){
ifstream tmp(path_[0]+name_[0]+".cpp");
if(tmp.is_open()) system(("g++ "+compile+" -o "+path_[0]+name_[0]+".exe "+path_[0]+name_[0]+".cpp").c_str());
else print("Can't compile "+name_[0]+".cpp\n",7),f=1;
}
if(!U.is_open()&&need_[1]=='T'){
ifstream tmp(path_[1]+name_[1]+".cpp");
if(tmp.is_open()) system(("g++ "+compile+" -o "+path_[1]+name_[1]+".exe "+path_[1]+name_[1]+".cpp").c_str());
else print("Can't compile "+name_[1]+".cpp\n",7),f=1;
}
if(!A.is_open()&&need_[2]=='T'){
ifstream tmp(path_[2]+name_[2]+".cpp");
if(tmp.is_open()) system(("g++ "+compile+" -o "+path_[2]+name_[2]+".exe "+path_[2]+name_[2]+".cpp").c_str());
else print("Can't compile "+name_[2]+".cpp\n",7),f=1;
}
if(!C.is_open()){
ifstream tmp(path_[3]+name_[3]+".cpp");
if(tmp.is_open()) system(("g++ "+compile+" -o "+path_[3]+name_[3]+".exe "+path_[3]+name_[3]+".cpp").c_str());
else print("Can't compile "+name_[3]+".cpp\n",7),f=1;
}
return f;
}
string oder[100];
int tot=1;
void translate(string s){
for(int i=1;i<=tot;++i) oder[i]="";
tot=1;int len=s.length();
for(int i=0;i<len;++i){
if(s[i]==' '){
if(oder[tot].length()) oder[++tot]="";
continue;
}
oder[tot]+=s[i];
}
}
void Compile(){
ifstream G,U,A;
G.open(path_[0]+name_[0]+".cpp");
U.open(path_[1]+name_[1]+".cpp");
A.open(path_[2]+name_[2]+".cpp");
if(G.is_open()&&need_[0]=='T') system(("g++ "+compile+" -o "+path_[0]+name_[0]+".exe "+path_[0]+name_[0]+".cpp").c_str());
if(U.is_open()&&need_[1]=='T') system(("g++ "+compile+" -o "+path_[1]+name_[1]+".exe "+path_[1]+name_[1]+".cpp").c_str());
if(A.is_open()&&need_[2]=='T') system(("g++ "+compile+" -o "+path_[2]+name_[2]+".exe "+path_[2]+name_[2]+".cpp").c_str());
}
void save_plan(string name){
if(opendir("plans")==NULL){
mkdir("plans");
}
ofstream fout("plans\\"+name);
for(int i=0;i<7;++i) fout<<name_[i]<<'\n';
for(int i=0;i<5;++i) fout<<path_[i]<<'\n';
fout<<compile<<'\n';
fout<<need_<<'\n';
fout<<auto_compile<<'\n';
}
void apply_plan(string name){
ifstream fin("plans\\"+name);
if(!fin.is_open()){
cout<<">Can't find "+name<<'\n';
return;
}
for(int i=0;i<7;++i) fin>>name_[i];
for(int i=0;i<5;++i) fin>>path_[i];
Getline(fin,compile);
fin>>need_;
fin>>auto_compile;
}
void lock(){
string password;
while(cin>>password&&password!="237051146");
cout<<"Unclocked!\n";
system("pause");
system("cls");
}
signed main(){
lock();
string s;
cout<<">>";
while(getline(cin,s)){
translate(s);
if(oder[1]=="start"){
test_num=oder[2];
if(test_num==""){
cout<<"<times>";
cin>>test_num;
}
if(check()) goto nxt;
if(auto_compile) Compile();
system(merge().c_str());
}else
if(oder[1]=="close"){
if(oder[2]==""){
cout<<"\tG: Generator\t"<<(need_[0]=='T'?"true":"false")<<'\n';
cout<<"\tU: User \t"<<(need_[1]=='T'?"true":"false")<<'\n';
cout<<"\tA: Answer \t"<<(need_[2]=='T'?"true":"false")<<'\n';
cout<<"\tauto: Automatic compilation\t"<<(auto_compile?"true":"false")<<'\n';
cout<<"\tall: G,U and A\n";
cout<<"<option>";
cin>>oder[2];tot=2;
}
for(int i=2;i<=tot;++i){
if(oder[i]=="G") need_[0]='F';
else if(oder[i]=="U") need_[1]='F';
else if(oder[i]=="A") need_[2]='F';
else if(oder[i]=="All") need_[0]=need_[1]=need_[2]='F';
else if(oder[i]=="auto") auto_compile=0;
else cout<<">What is \""+oder[i]+"\" ?\n";
}
}else
if(oder[1]=="need"){
if(oder[2]==""){
cout<<"\tG: Generator\t"<<(need_[0]=='T'?"true":"false")<<'\n';
cout<<"\tU: User \t"<<(need_[1]=='T'?"true":"false")<<'\n';
cout<<"\tA: Answer \t"<<(need_[2]=='T'?"true":"false")<<'\n';
cout<<"\tauto: Automatic compilation\t"<<(auto_compile?"true":"false")<<'\n';
cout<<"\tall: G,U and A\n";
cout<<"<option>";
cin>>oder[2];tot=2;
}
for(int i=2;i<=tot;++i){
if(oder[i]=="G") need_[0]='T';
else if(oder[i]=="U") need_[1]='T';
else if(oder[i]=="A") need_[2]='T';
else if(oder[i]=="all") need_[0]=need_[1]=need_[2]='T';
else if(oder[i]=="auto") auto_compile=1;
else cout<<">What is \""+oder[i]+"\" ?\n";
}
}else
if(oder[1]=="open"){
if(oder[2]==""){
cout<<"\tG : Generator\n";
cout<<"\tU : User's\n";
cout<<"\tA : Answer\n";
cout<<"\tC : Checker\n";
cout<<"\tWA : input of WA\n";
cout<<"\tP : Programs\n";
cout<<"\tallP: G,U,A and C\n";
cout<<"<option>";
cin>>oder[2];tot=2;
}
if(oder[2]=="allP"){
tot=6;
oder[2]="G";oder[3]="U";oder[4]="A";
oder[5]="C";
}
for(int i=2;i<=tot;++i){
if(oder[i]=="G") system("start program\\generator");
else if(oder[i]=="U") system("start program\\user");
else if(oder[i]=="A") system("start program\\answer");
else if(oder[i]=="C") system("start program\\checker");
else if(oder[i]=="WA") system("start WA-input");
else if(oder[i]=="P") system("start program");
else cout<<">What is \""+oder[i]+"\" ?\n";
}
}else
if(oder[1]=="show"){
if(oder[2]==""){
cout<<"<name/path/need/compile/plan>";
cin>>oder[2];tot=2;
}
if(oder[2]=="all"){
tot=5;
oder[2]="name";
oder[3]="path";
oder[4]="need";
oder[5]="compile";
}
if(oder[2]=="plan"&&oder[3]==""){
cout<<"<plan name>";
cin>>oder[3];tot=3;
}
if(oder[2]=="plan"){
ifstream fin("plans\\"+oder[3]);
if(!fin.is_open()){
cout<<">can't find "+oder[3]<<'\n';
goto nxt;
}
string tmp;
for(int i=0;i<7;++i){
fin>>tmp;
cout<<'\t'<<show_name[i]<<":\t"<<tmp<<'\n';
}
for(int i=0;i<4;++i){
fin>>tmp;
cout<<'\t'<<show_name[i]<<":\t"<<tmp<<'\n';
}
fin>>tmp;
cout<<"\tChecker to program:\t"<<tmp<<'\n';
Getline(fin,tmp);
cout<<"\tCompile command:\t"<<tmp<<'\n';
char tmp_;
for(int i=0;i<3;++i){
fin>>tmp_;
cout<<'\t'<<show_name[i]<<":\t"<<(tmp_=='T'?"true\n":"false\n");
}
fin>>tmp_;
cout<<"\tAutomatic compilation\t"<<(tmp_=='1'?"true\n":"false\n");
}else
for(int i=2;i<=tot;++i){
if(oder[i]=="name"){
cout<<">Name:\n";
for(int i=0;i<7;++i)
cout<<'\t'<<show_name[i]<<": "<<name_[i]<<'\n';
}
else if(oder[i]=="path"){
cout<<">Path:\n";
for(int i=0;i<4;++i)
cout<<'\t'<<show_name[i]<<": "<<path_[i]<<'\n';
cout<<"\tChecker to program:\t"<<path_[4]<<'\n';
}
else if(oder[i]=="need"){
cout<<">Need:\n";
for(int i=0;i<3;++i)
cout<<'\t'<<show_name[i]<<": "<<(need_[i]=='T'?"true\n":"false\n");
cout<<"\tAutomatic compilation: "<<(auto_compile?"true\n":"false\n");
}
else if(oder[i]=="compile"){
cout<<">Compile:\n";
cout<<'\t'<<compile<<'\n';
}
else cout<<">What is \""+oder[i]+"\" ?\n";
}
}else
if(oder[1]=="change"){
string tmp1=oder[2],tmp2=oder[3],tmp3=oder[4];
int x=0;
if(tmp1!="name"&&tmp1!="path"&&tmp1!="need"&&tmp1!="compile"){
cout<<"<name/path/need/compile>";
cin>>tmp1;
}
if(tmp1=="compile"){
tmp2="";
cout<<"<command>";
Getline(cin,tmp2);
}else if(!isNum(tmp2)){
if(tmp1=="name"){
for(int i=0;i<7;++i) cout<<'\t'<<i<<": "<<show_name[i]<<'\n';
}else
if(tmp1=="path"){
for(int i=0;i<5;++i) cout<<'\t'<<i<<": "<<show_name[i]<<'\n';
}else
if(tmp1=="need"){
for(int i=0;i<3;++i) cout<<'\t'<<i<<": "<<show_name[i]<<'\n';
cout<<"\t3: Automatic compilation\n";
}
cout<<"<number>";
while(cin>>tmp2&&!isNum(tmp2)) cout<<"<number>";
}
if(tmp3==""&&tmp1!="compile"){
if(tmp1=="name"){
cout<<"<file name>";
cin>>tmp3;
}else
if(tmp1=="path"){
cout<<"<path>";
cin>>tmp3;
}else
if(tmp1=="need"){
cout<<"<true/false>";
cin>>tmp3;
}
}
if(tmp1!="compile") x=stoi(tmp2);
if(tmp1=="name"){
if(x<7) name_[x]=tmp3;
else cout<<"Error\n";
}
if(tmp1=="path"){
if(x<5) path_[x]=tmp3;
else cout<<"Error\n";
}
if(tmp1=="need"){
need_[x]=(tmp3=="true"?'T':'F');
if(x==3) auto_compile=(tmp3=="true");
}
if(tmp1=="compile"){
compile=tmp2;
}
}else
if(oder[1]=="save"){
if(oder[2]==""){
cout<<"<plan name>";
cin>>oder[2];tot++;
}
save_plan(oder[2]);
}else
if(oder[1]=="apply"){
if(oder[2]==""){
cout<<"<plan name>";
cin>>oder[2];tot++;
}
apply_plan(oder[2]);
}
else system(s.c_str());
nxt:;
if(s!="") cout<<">>";
}
return 0;
}
Leader
#include<bits/stdc++.h>
#include<windows.h>
using namespace std;
void color(int c){
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(handle, c);
}
void print(string s,int col){
color(col);
cerr<<s;
color(7);
}
int test_num=10;
bool need_Generator=1,need_Answer=1,need_User=1;
string _name[10],_path[10];
// _name[0]="Generator",
// _name[1]="User",
// _name[2]="Answer",
// _name[3]="Checker",
// _name[4]="input.in",
// _name[5]="output.out",
// _name[6]="output.ans",
//
// _path[0]="program\\generator\\",
// _path[1]="program\\user\\",
// _path[2]="program\\answer\\",
// _path[3]="program\\checker\\",
// _path[4]="..\\..\\"
ifstream G,A,U,C,cpyin;
ofstream cpyout;
void check(){
bool f=0;
G.open(_path[0]+_name[0]+".exe");
A.open(_path[2]+_name[2]+".exe");
U.open(_path[1]+_name[1]+".exe");
C.open(_path[3]+_name[3]+".exe");
if(!G.is_open()&&need_Generator){
print("\tCan't find "+_name[0]+".exe",7),f=1;
}
if(!A.is_open()&&need_Answer){
print("\tCan't find "+_name[2]+".exe",7),f=1;
}
if(!U.is_open()&&need_User){
print("\tCan't find "+_name[1]+".exe",7),f=1;
}
if(!C.is_open()){
print("\tCan't find "+_name[3]+".exe",7),f=1;
}
if(f) exit(0);
}
void initialize(int argn,char* argv[]){
need_Generator=(argv[1][0]=='T');
need_User=(argv[1][1]=='T');
need_Answer=(argv[1][2]=='T');
_name[0]=argv[2];
_name[1]=argv[3];
_name[2]=argv[4];
_name[3]=argv[5];
_name[4]=argv[6];
_name[5]=argv[7];
_name[6]=argv[8];
_path[0]=argv[9];
_path[1]=argv[10];
_path[2]=argv[11];
_path[3]=argv[12];
_path[4]=argv[13];
test_num=atoi(argv[14]);
}
signed main(int argn,char* argv[]){
initialize(argn,argv);
clock_t st,ed;
int res=-1;
//检查所需程序是否完全
check();
for(int test_id=1;test_id<=test_num;++test_id){
//测试点编号
cout<<"test "<<test_id<<" :\t\t";
if(need_Generator) system((_path[0]+_name[0]+".exe "+_name[4]).c_str());
if(need_Answer) system((_path[2]+_name[2]+".exe").c_str());
st=clock();
if(need_User) res=system((_path[1]+_name[1]+".exe").c_str());
ed=clock();
if(res&&need_User) print("Runtime Error: Your program returned "+to_string(res)+".\t\t"+to_string(ed-st)+" ms",14);
else{
res=system((_path[3]+_name[3]+".exe "+_path[4]+_name[4]+' '+_path[5]+_name[5]+' '+_path[6]+_name[6]).c_str());
if(res>=0) print("\t\t"+to_string(ed-st)+" ms",7);
if(res!=0){
cpyin.open(_name[4],ios::binary);
cpyout.open("WA-input\\test "+to_string(test_id)+".in",ios::binary);
cpyout<<cpyin.rdbuf();
cpyin.close();
cpyout.close();
}
}
cout<<'\n';
}
return 0;
}
Generator
#include<bits/stdc++.h>
#include<tuple>
#include<vector>
#define uint unsigned int
#define ll long long
#define ull unsigned long long
#define dbl double
#define TIME chrono::system_clock::now().time_since_epoch().count()
using namespace std;
mt19937_64 num(TIME);
template<typename T>inline T INT(T l,T r,char out=0){T x=num()%(r-l+1)+l;if(out)cout<<x<<out;return x;}
template<typename T>inline vector<T> INT(int len,T l,T r,char out=0,char out2=0){vector<T> v(len);for(int i=0;i<len;++i) v[i]=INT(l,r,out);if(out2) cout<<out2;return v;}
template<typename T>inline T FLO(T l,T r,char out=0,int pos=3){
uniform_real_distribution<long double> flo(l,r);
T x=flo(num);
if(out) cout<<fixed<<setprecision(pos)<<x<<out;
return x;
}
template<typename T>inline vector<T> FLO(int len,T l,T r,char out=0,char out2=0,int pos=3){
vector<T> v(len);
for(int i=0;i<len;++i) v[i]=FLO(l,r,out,pos);
if(out2) cout<<out2;
return v;
}
inline char CH(char l,char r,char out=0){char x=num()%(r-l+1)+l;if(out)cout<<x<<out;return x;}
inline char CH(string s,char out=0){char x=s[INT(0,(int)s.size()-1)];if(out)cout<<x<<out;return x;}
inline string STR(int len,char l,char r,char out=0,char out2=0){string s;for(int i=1;i<=len;++i) s+=CH(l,r,out);if(out2) cout<<out2;return s;}
template<typename T> inline T Pick(initializer_list<T> s,char out=0){
T x=*(s.begin()+num()%s.size());
if(out) cout<<x<<out;
return x;
}
template<typename T>inline vector<T> Pick(int len,initializer_list<T> s,char out=0,char out2=0){
vector<T> v(len);
for(int i=0;i<len;++i) v[i]=Pick(s,out);
if(out2) cout<<out2;
return v;
}
pair<int,int> ITV(int l,int r,char out=0){
int x=INT(l,r),y=INT(l,r);
if(x>y) swap(x,y);
if(out) cout<<x<<' '<<y<<out;
return {x,y};
}
auto Graph(int point,int edge,int weightl=0,int weightr=0,vector<string> t={}){
map<string,bool> type;
for(string s:t) type[s]=1;
bool repeat=type["repeat"],directed=type["directed"],
forest=type["forest"],self=type["self"],
heap=type["max-heap"]|type["min-heap"]|type["heap"];
vector<tuple<int,int,int> > g;
map<pair<int,int>,bool> vis;
vector<int> tmp;
if(type["max-heap"]) for(int i=point;i>=1;--i) tmp.emplace_back(i);
else for(int i=1;i<=point;++i) tmp.emplace_back(i);
if(!heap) shuffle(tmp.begin(),tmp.end(),num);
if(!forest)
for(int i=1,x,y;i<(int)tmp.size();++i){
x=tmp[INT(0,i-1)],y=tmp[i];
if(!repeat){
if(directed)vis[{x,y}]=1;
else vis[{x,y}]=vis[{y,x}]=1;
}
g.emplace_back((tuple<int,int,int>){x,y,INT(weightl,weightr)});
}
if(!forest) edge-=point-1;
if(!type["tree"])
while(edge>0){
int x=INT(1,point),y=INT(1,point);
while(vis[{x,y}]||(x==y&&!self)) x=INT(1,point),y=INT(1,point);
if(!repeat){
if(directed)vis[{x,y}]=1;
else vis[{x,y}]=vis[{y,x}]=1;
}
g.emplace_back((tuple<int,int,int>){x,y,INT(weightl,weightr)});
edge--;
}
if(type["value"]) for(auto x:g)cout<<get<0>(x)<<' '<<get<1>(x)<<' '<<get<2>(x)<<'\n';
else if(type["out"]) for(auto x:g)cout<<get<0>(x)<<' '<<get<1>(x)<<'\n';
return g;
}
void Generate(){
//write here!!!!!!!!!!!!!!!!
}
signed main(int argn,char* argv[]){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
if(argn==2) freopen(argv[1],"w",stdout);
Generate();
return 0;
}
Checker
#include<bits/stdc++.h>
#include<windows.h>
using namespace std;
ifstream ain,uin;
/*
return 0: Accepted
return 1: Wrong answer: Objective wrong answer
return 2: Wrong answer: Output longer than answer
return 3: Wrong answer: Output shorter than answer
return -1: System error: can't find corrent.out
return -2: System error: can't find tested.out
else System error: Unknown Error
*/
void color(int c){
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(handle, c);
}
void print(string s,int col){
color(col);
cerr<<s;
color(7);
}
string user,answer,input;
int Judge(){
//Write Special Judge here
string s1,s2;
bool f=1;
while(ain>>s1&&uin>>s2){
if(s1!=s2) f=0;s1="",s2="";
}
ain>>s1;uin>>s2;
if(s1==""&&s2!="") return 2;
if(s2==""&&s1!="") return 3;
if(f) return 0;
else return 1;
}
signed main(int argn,char* argv[]){
input=argv[1];
user=argv[2];
answer=argv[3];
ios::sync_with_stdio(0);
ain.tie(0),uin.tie(0);
ain.open(answer);
uin.open(user);
if(!ain.is_open()) return -1;
if(!uin.is_open()) return -2;
int res=Judge();
if(res==0){
print("Accepted!",10);
}else
if(res==1){
print("Wrong answer: Objective wrong answer",4);
}else
if(res==2){
print("Wrong answer: Output longer than answer",4);
}else
if(res==3){
print("Wrong answer: Output shorter than answer",4);
}else
if(res==-1){
print("System error: can't find "+answer,13);
}else
if(res==-2){
print("System error: can't find "+user,13);
}else{
print("System error: Unknown Error",13);
}
return res;
}
更新日志
- 2026/7/25 16:05 略微降低了生成树的空间开销。
- 2026/7/25 16:39 Graph函数更新了
heap、min-heap、max-heap命令。更新了排版。 - 2026/7/25 20:51 加入了答案比较器、对拍启动器、正确程序头与待测程序头,至此,完整对拍程序已经完工。
- 2026/7/26 10:39 更新1.1测试版,加入计时功能。
- 2026/7/26 10:48 将此文章同步与洛谷。
- 2026/7/26 19:14 更新1.1.1正式版优化了Special Judge的书写难度,新增了
RE、UKE报错。 - 2026/7/26 20:19 修复了一些BUG。由于不同编译器对中文注释的处理不同,将中文注释改为了英文注释,并优化了文件的大小。
- 2026/7/27~2026/7/31 陆续发布了1.1.2(测试)、1.1.3(正式)、1.1.4(正式)
不知道什么时候更新了1.1.5、1.2.0- 2026/8/18: 发布了2.0(测试)
- 2026/8/21: 发布了2.0(用户版)、2.0(开源),更新了文章排版。
更新内容:
2.0:
大更新!!!!
内容较多。
1.2.0:
- 加入测试性加入指令。
1.1.5:
- 测试性加入随机排列。
1.1.4(正式):
- 加入了Warning报错。
- 正式加入报错信息说明。
- 优化了Special Judge的书写环境。
- 优化了文章排版。
1.1.3(正式):
- 修复了1.1.2模板函数的锅。
- 更改了「随机样例生成器」的生成随机数函数。
- 加入了随机浮点数的生成。
- 从原函数分离出Pick()函数。
1.1.2(测试):
- 尝试加入报错信息说明。
- 使用模板函数合并相似函数(也出了巨大的锅)。
1.1.1(正式):
- 优化了Special Judge书写。
- 新增
RE、UKE报错。
1.1(测试):
- 加入计时功能。
1.0 :
- 完整对拍程序,可以完成对拍。
通知
3.0版本正在加紧制作中
是的没错这作者又开始代码重构了

浙公网安备 33010602011771号