[模板]数据生成与对拍

[模板]数据生成与对拍

不断完善中...

对拍

轻便装(比赛用)

#include <bits/stdc++.h>
using namespace std;
const string file1 = ".exe";
const string file2 = ".exe";
const string random = ".exe";
const bool TLEstop = false;

void getseed() {
	static ofstream fout("seed");
	fout << rand(); 
}

void run(string f , string input , string output) {
	int t = clock();
	
	printf("running %s\n" , f.c_str());
	if(system((f + " < " + input + " > " + output).c_str()) != 0) {
		printf("\tRuntimeError\n");
		exit(0);
	}
	printf("\tfinished in %d ms.\n" , clock() - t);
	if(clock() - t > 1000 && TLEstop)
		system("pause");
}
int main() {
	srand(time(0));
	
	int cnt = 0;
	while(true) {
		printf("#%d\n" , ++cnt);
		getseed();
		run(random , "seed" , "input.txt");
		run(file1 , "input.txt" , "output1.txt");
		run(file2 , "input.txt" , "output2.txt");
		if(system("fc output1.txt output2.txt")) {
			puts("WrongAns");
			return 0;
		}
	}
	return 0;
}

完整版(平时用)

#include <bits/stdc++.h>
using namespace std;
string randomfile = "random.exe";
string file1 = "#1.exe";
string file2 = "#1-1.exe";
bool TLEstop = true;
int limit = 1000;

//说明一下,随机数据生成使用的srand((unsigned)time(0))中time(0)的单位为秒,这也就意味着两次时间差很小的数据得到的随机种子是一样的,即生成的数据一模一样,这就需要从外面读入种子而保证生成的数据不同 
void putseed() { 
	ofstream fout("seed");//以输出方式打开文件 
	fout << (unsigned)rand() * rand() * rand();
	fout.close();
}
int main() {
	srand((unsigned)time(0));
	
	int sum1 = 0;
	int sum2 = 0;
	int cnt = 0;
	while(true) {
		++cnt;
		putchar('\n');
		printf("<========================#%d========================>\n" , cnt);
		
		//random
		puts(randomfile.c_str());
		puts("\trunning");
		putseed();
		system((randomfile + " < seed" + " > input.txt").c_str());
		puts("\tfinished");
		
		putchar('\n');
		
		//file1
		int t = clock();
		puts(file1.c_str());
		puts("\trunning");
		if(system((file1 + " < input.txt > output1.txt").c_str()) != 0) {
			puts("\tRE");
			break;
		}
		puts("\tfinished");
		printf("\t%dms\n" , clock() - t);
		printf("\t平均用时:%.3fms\n" , 1.0 * (sum1 += clock() - t) / cnt);
		if(TLEstop && clock() - t > limit) {
			puts("TLE");
			system("pause");
		}
		putchar('\n');
		
		//file2
		t = clock();
		puts(file2.c_str());
		puts("\trunning");
		if(system((file2 + " < input.txt > output2.txt").c_str()) != 0) {
			puts("\tRE");
			break;
		}
		puts("\tfinished");
		printf("\t%dms\n" , clock() - t);
		printf("\t平均用时:%.3fms\n" , 1.0 * (sum2 += clock() - t) / cnt);
		if(TLEstop && clock() - t > limit) {
			puts("TLE");
			system("pause");
		}
		putchar('\n');
		
		if(system("fc output1.txt output2.txt")) {
			puts("WA");
			break;
		}
	}
	system("start input.txt");
	return 0;
}

测评自动机

请确认数据文件夹中没有任何其它文件,且读入文件以".in"为后缀
采用多线程监视程序超时情况

数据文件默认为下面形式(*代表任意字符):

*1.in	*1.*
*2.in	*2.*
......

第二版

加入了超时强行退出机制

#include <direct.h>
#include <io.h>
#include <fstream>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <windows.h>
#include <algorithm>
#include <ctime>

#include <pthread.h>
using namespace std;
string path = "call//";//数据路径
string tested = "#3.exe";//被测评程序
int limit = 3000;//ms 时限


string a;
int reval;
bool TLE_check;
bool fini;
bool fini2;
int run_time;
//=======================================================
void* run_(void* args)
{
	run_time = clock();
	reval = system(a.c_str());
	run_time = clock() - run_time;
	fini = true;
}
void* limit_(void* args)
{
	int t = 0;
	while(t < limit) {
		Sleep(50);
		t += 50; 
		if(fini)break;
	}
	if(!fini) {
		system(("TASKKILL /F /IM " + tested + " /T").c_str());
		TLE_check = true;
	}
	fini2 = true;
}
//========================================================

vector <string> file;

void GetAllFiles() {//获取文件名,不用管
	long   hFile   =   0;
	struct _finddata_t fileinfo;
	string p;
	if((hFile = _findfirst(p.assign(path).append("\\*").c_str(),&fileinfo)) !=  -1)
	{ 
//		label: ;
		system("cls");
		do {
			if(p.assign(fileinfo.name) != "." && p.assign(fileinfo.name) != "..")
				file.push_back(p.assign(fileinfo.name) );
		} while(_findnext(hFile, &fileinfo)  == 0);
		_findclose(hFile);
	}

}

struct node{
	string s;
	int key;//文件序号
	void getkey() {
		key = 0;
		for(int i = 0 ; i < s.size() ; i++)
			if(s[i] >= '0' && s[i] <= '9') {
				if(i != 0)	if(s[i - 1] < '0' || s[i - 1] > '9')key = 0;
				key = key * 10 + s[i] - '0';
			}
				
	}
};
vector <node> input;
vector <node> ans; 
bool cmp(node a , node b) {
	return a.key < b.key;
}
int main() {
	GetAllFiles();
	int siz = file.size();
	for(int i = 0 ; i < siz  ; i++) {
		node tmp;
		tmp.s = file[i];
		tmp.getkey();
		if(file[i].substr(file[i].size() - 2) == "in") {
			
			input.push_back(tmp);
		}
		else
			ans.push_back(tmp);
	}
	
	
	sort(input.begin() , input.end() , cmp);
	sort(ans.begin() , ans.end() , cmp);
	for(int i = 0 ; i < input.size() ; i++) {
		printf("#%d\n" , i + 1);
		cout << input[i].s << endl;
		cout << ans[i].s << endl;
		putchar('\n');
	}
	
	puts("check the files");
	system("pause");
	
	int TLE = 0 , WA = 0 , AC = 0 , RE = 0;
	int tot = 0;
	int tim[110];
	int sta[110];
	for(int k = 0 ; k < input.size() ; k++) {
		string i = input[k].s;
		string o = ans[k].s;
		
		tot++;
		tim[tot] = 0;
		int t = clock();
		
		//=============
		a = (tested + " < " + path + i + " > output.txt");
		
		pthread_t close;
		pthread_t run;
		int ret = 0;
		reval = -1;
		TLE_check = false;
		fini = fini2 = false;
		ret = pthread_create(&run, NULL, run_, NULL);
		ret = pthread_create(&close, NULL, limit_, NULL);
		while(!fini && !fini2) {
			Sleep(50);
		}
		//=============
		if(reval != 0 && TLE_check == false) {
			RE++;
			sta[tot] = 0;
			continue;
		}
		
		tim[tot] = run_time;
		if(TLE_check == true) {
			TLE++;
			sta[tot] = 1;
			continue;
		}
		if(system(("fc output.txt " + path + o).c_str())) {
			WA++;
			sta[tot] = 2;
			continue;
		}
		
		AC++;
		sta[tot] = 3;
	}
	
	for(int i = 1 ; i <= tot ; i++) {
		printf("#%d:\n" , i);
		puts(("\t" + (string)(sta[i] <= 1 ? (sta[i] == 0 ? "RE" : "TLE") : (sta[i] == 2 ? "WA" : "AC") ) ).c_str());
		if(sta[i] != 0) {
			printf("\ttime:%dms\n" , tim[i]);
		}
	}
	putchar('\n');
	printf("得分:%.3f" , 100.0 * AC / tot );
	
    //等各个线程退出后,进程才结束,否则进程强制结束了,线程可能还没反应过来;
    pthread_exit(NULL);
	return 0;
}

第一版

#include <direct.h>
#include <io.h>
#include <fstream>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <windows.h>
#include <algorithm>
#include <ctime>
using namespace std;
string path = "data//";//数据路径
string tested = "1.exe";//被测评程序
int limit = 3000;//ms 时限

vector <string> file;

void GetAllFiles() {//获取文件名,不用管
	long   hFile   =   0;
	struct _finddata_t fileinfo;
	string p;
	if((hFile = _findfirst(p.assign(path).append("\\*").c_str(),&fileinfo)) !=  -1)
	{ 
		label: ;
		system("cls");
		do {
			if(p.assign(fileinfo.name) != "." && p.assign(fileinfo.name) != "..")
				file.push_back(p.assign(fileinfo.name) );
		} while(_findnext(hFile, &fileinfo)  == 0);
		_findclose(hFile);
	}

}

struct node{
	string s;
	int key;//文件序号
	void getkey() {
		key = 0;
		for(int i = 0 ; i < s.size() ; i++)
			if(s[i] >= '0' && s[i] <= '9') {
				if(i != 0)	if(s[i - 1] < '0' || s[i - 1] > '9')key = 0;
				key = key * 10 + s[i] - '0';
			}
				
	}
};
vector <node> input;
vector <node> ans; 
bool cmp(node a , node b) {
	return a.key < b.key;
}
int main() {
	GetAllFiles();
	int siz = file.size();
	for(int i = 0 ; i < siz  ; i++) {
		node tmp;
		tmp.s = file[i];
		tmp.getkey();
		if(file[i].substr(file[i].size() - 2) == "in") {
			
			input.push_back(tmp);
		}
		else
			ans.push_back(tmp);
	}
	
	
	sort(input.begin() , input.end() , cmp);
	sort(ans.begin() , ans.end() , cmp);
	for(int i = 0 ; i < input.size() ; i++) {
		printf("#%d\n" , i + 1);
		cout << input[i].s << endl;
		cout << ans[i].s << endl;
		putchar('\n');
	}
	
	puts("check the files");
	system("pause");
	
	int TLE = 0 , WA = 0 , AC = 0 , RE = 0;
	int tot = 0;
	int tim[110];
	int sta[110];
	for(int k = 0 ; k < input.size() ; k++) {
		string i = input[k].s;
		string o = ans[k].s;
		
		tot++;
		tim[tot] = 0;
		int t = clock();
		if(system((tested + " < " + path + i + " > output.txt").c_str()) != 0) {
			RE++;
			sta[tot] = 0;
			continue;
		}
		tim[tot] = clock() - t;
		if(tim[tot] > limit) {
			TLE++;
			sta[tot] = 1;
			continue;
		}
		if(system(("fc output.txt " + path + o).c_str())) {
			WA++;
			sta[tot] = 2;
			continue;
		}
		
		AC++;
		sta[tot] = 3;
	}
	
	for(int i = 1 ; i <= tot ; i++) {
		printf("#%d:\n" , i);
		puts(("\t" + (string)(sta[i] <= 1 ? (sta[i] == 0 ? "RE" : "TLE") : (sta[i] == 2 ? "WA" : "AC") ) ).c_str());
		if(sta[i] != 0) {
			printf("\ttime:%dms\n" , tim[i]);
		}
	}
	putchar('\n');
	printf("得分:%.3f" , 100.0 * AC / tot );
	return 0;
}

数据生成

基础模板

#include <bits/stdc++.h>
using namespace std;
int random(int r , int l = 1) {
	int x = 0;
	for(int i = 1 ; i <= 29 ; i++)
		x = (x << 1) + (rand() & 1);
	return x % (r - l + 1) + l;
}
int main() {
	unsigned seed;
	cin >> seed;
	srand(seed * time(0));
	
    
	return 0;
}

随机生成树

//针对洛谷P3397:LCA模板
#include <bits/stdc++.h>
using namespace std;
int random(int r , int l = 1) {
	return (long long) rand() * rand() % (r - l + 1) + l; 
}
pair <int,int> ed[1000010];
int dict[1000010];//用于打乱结点编号,有些有向图不适用
int main() {
	unsigned seed;
	cin >> seed;
	seed *= time(0);
	srand(seed);//外界输入种子
	
	int n = random(500000) , m = random(500000);
	for(int i = 1 ; i <= n ; i++)
		dict[i] = i;
	random_shuffle(dict + 1 , dict + n + 1);
	for(int i = 1 ; i < n ; i++) {
		ed[i].first = random(i);
		ed[i].second = i + 1;
	}
	printf("%d %d %d\n" , n , m , random(n));
	
	random_shuffle(ed + 1 , ed + n);//随机打乱
	for(int i = 1 ;i < n ; i++)
		printf("%d %d\n" , dict[ed[i].first] , dict[ed[i].second]);
	
	for(int i = 1 ; i<= m ; i++)//查询LCA
		printf("%d %d\n" , random(n) , random(n));
	return 0;
}

随机生成图

//无向图,带权边	有向图适当修改即可
#include <bits/stdc++.h>
#define ull unsigned long long
using namespace std;
int random(int r , int l = 1) {
	return (long long) rand() * rand() * rand() % (r - l + 1) + l;
}

#define nn 100010
map <ull , bool> h;

int n , m ;
int dict[nn];
struct node {
	int x , y;
} ed[nn * 5];

#define value(_ , __) ((ull)n * (_) + (__))//hash
int main() {
	unsigned seed;
	cin >> seed;
	seed *= time(0);
	srand(seed);

	int n = random(300 , 2) , m = random(n * 10 , n) ;

	if(m > n * (n - 1) / 2)
		m = n * (n - 1) / 2;
		
	for(int i = 1 ; i <= n ; i++)
		dict[i] = i;

	for(int i = 2 ; i <= n ; i++) {//生成树以保证图连通
		ed[i - 1].y = i;
		ed[i - 1].x = random(i - 1);
		h[value(ed[i - 1].x , ed[i -1 ].y)]	= true;
		h[value(ed[i - 1].y , ed[i -1 ].x)]	= true;
		
	}
	for(int i = n ; i <= m ; i++) {
		int x , y;
		do
			x = random(n) , y = random(n);
		while(x == y || h[value(x , y)] == true);//如果m开得太接近n*(n-1)/2,这里会很吃力
		
		ed[i].x = x , ed[i].y = y;
		h[value(x , y)] = h[value(y , x)] = true;
		
	}
	random_shuffle(ed + 1 , ed + m + 1);
	random_shuffle(dict + 1 , dict + n + 1);

	printf("%d %d\n" , n , m);
	for(int i = 1 ; i <= m ; i++) {
		printf("%d %d %d\n" , dict[ed[i].x] , dict[ed[i].y] , random(1e6));
	}

	return 0;
}

造数据

以洛谷为标准

链接

上传压缩包的要求

  • 直接将若干数据点打包成一个 zip 压缩包,rar 和其他格式不能成功。
  • 输入数据和输出数据应当成对出现,其输入数据文件的扩展名为 .in 而输出文件的扩展名为 .out
  • 没有任何文件夹或者其他无关文件,压缩后大小不超过 50M。
  • 测试点文件名中只能允许有连续的一段数字,例如 game001.in 可以,而 T1-1.ingame.in 不可以。

测试点配置要求

  • 普通用户的测试点数量不能超过 50 对,单测试点最多运行 10s,内存 512M。
  • 如果需要设置子任务,需要从 0 开始编号。

题目测试点配置文件

在上传题目数据时可以直接在网页中设置测试点的时间、内存限制等信息,但如果重复更新数据,每次都要重设很麻烦,就可以使用测试点配置文件。

详见:题目测试点配置文件

Special Judge 使用说明

当一个题目可以接受多种正确答案,即有多组解的时候,题目就必须被 Special Judge。 Special Judge 程序使用输入数据和一些其他信息来判答你程序的输出,并将判答结果返回。

详见:Special Judge 使用说明

自定义计分脚本

有的时候出了一道题想要自定义比较复杂的计分策略,但是单靠 Subtask 的组合无法满足,这时候可以使用计分脚本。

详见:自定义计分脚本

交互题功能说明

交互题既用户提交的程序,通过出题人提供的交互库,与判题程序(SPJ)进行交互并获得输入、解答问题。

详见:交互题功能说明

#include <bits/stdc++.h>
using namespace std;
string random = "random.exe";	//随机数据文件
string stdcode = "std.exe";		//标准程序
string name = "replace";		//数据文件名(不能含空格)

string itos(unsigned x) {
	string s;
	do
		s = (char)(x % 10 + '0') + s , x /= 10;
	while(x != 0);
	return s;
}
void putseed() { 
	ofstream fout("seed");
	fout << (unsigned)rand() * rand() * rand();
	fout.close();
}

int main() {
	system("md data");
	for(int i = 1 ; i <= 50 ; i++) {//数据组数
		string in = name + "_" + itos(i) + ".in";
		string out =name + "_" + itos(i) + ".out";
		putseed();
		puts(("data " + itos(i) + " making").c_str());
		system( (random + " < seed > " + in).c_str() );
		puts(("data " + itos(i) + " .in finished").c_str());
		system( (stdcode + " < " + in + " > " + out).c_str() );
		puts(("data " + itos(i) + " .out finished").c_str());
		
		system( ("move " + in + " data\\" + in).c_str());
		system(("move " + out + " data\\" + out).c_str());
	}
	return 0;
}
posted @ 2020-11-28 08:32  追梦人1024  阅读(200)  评论(0编辑  收藏  举报