cena評測系統:自定義校驗器(自定義評測插件編寫)

Cena評測系統,最受歡迎的信息學競賽離線評測系統。

它是開放源程序的信息學競賽評測系統,能滿足大多數程序設計競賽的測評需求。

特色功能:

通過局域網自動收取選手程序。
高效率的數據文件配置工具。
自動選用對應的編譯器來編譯選手程序,也能使用解釋器或直接評測可執行文件。
能準確測出選手程序的運行時間和內存使用量,並可加入對運行時間和內存使用的限制。
自動比較選手程序的輸出和標準輸出的差異,並能將兩者出現差異的具體位置告訴評測者。
支持使用自定義校驗器,可評測有多解的試題。
可對評測結果進行統計分析。
可將評測結果以各種樣式打印或導出。

注意事項:

Cena 0.8.1 安裝程序: cena-0.8.1-20110710-setup.exe[1]  。如果它崩潰,就用這個補丁 cena-0.8.2-patch.zip 裏的文件覆蓋到安裝目錄。2011-08-21 發佈0.8.2版本。但願它不再崩潰。(截止2013年8月1日最新版)

自定義校驗器(Special Judge)編輯
Cena評測軟件提供了使用自定義校驗器進行評分的功能。可以使用C++或者Pascal進行編寫評測插件,其中Pascal需要載入軟件所提供的運行庫。cena的用處還是很大的,以下是一個關於自定義校驗器的模板,使用時需要放在data文件夾下,要有exe文件

cena的SJ主要是由pascal語言編寫的,其原因是cena附的用於SJ的庫函數是給pascal使用的。
那個庫文件位於cena安裝文件夾/lib/libcheck.pas。
使用時把寫好的SJ程序和libcheck.pas放到同一目錄下,然後編譯出exe。
在cena的試題配置選項卡當中,"比較方式"選"使用自定義校驗器",然後下面"自定義校驗器"一欄選擇剛剛編譯出來的exe就好了。
想用C++編寫SJ的朋友,我也百度到了一個不錯的模板。已經試用過了。下面會一起給出一個sample。當然C++代碼的編譯就和libcheck.pas沒關係了,確實省事一些。

{cena的幫助文件中對於libcheck.pas的說明}
{注意其中 fso : double 有誤,這一變量名應爲fsco}
libcheck.pas(位置:安裝路徑\lib\) 說明如下:
變量:
std: Text; { 用於讀取標準輸出文件 }
rep: Text; { 用於寫入校驗信息 }
fso: Double; { 爲這個測試點的滿分 }
過程:
procedure Score(AScore: Double); { 用於向評測系統報告得分 }
procedure Finish; { 結束 }
{這個是CEOI 2011 Day1 T1 balloons的SPJ的代碼}
{讀入n並判斷選手輸出的n個浮點數是否在允許的誤差範圍內}
uses
	libcheck;
var
	n,i: longint;
	x,y: extended;
	bin,bout: text;
procedure ends(x:double); {返回得分爲x並結束程序}
	begin
		score(x);
		writeln(rep,n,' lines checked');
		writeln(rep,'SJ by wyl8899');
		Finish;
		halt;
	end;
	begin
		assign(bin,'balloons.in'); reset(bin);
		readln(bin,n); close(bin);
		assign(bout,'balloons.out'); reset(bout);
		for i:=1 to n do
			begin
			readln(std,y);
			if seekeof(bout) then
				begin
					writeln(rep,'Output Too Short');
					ends(0);
				end;
				readln(bout,x);
				if (x-y>0.001001)or(y-x>0.001001) then
					begin
						writeln(rep,'Line ',i);
						writeln(rep,'Std:',y:0:3);
						writeln(rep,'W A:',x:0:3);
						ends(0);
					end;
				end;
				if not seekeof(bout) then
					begin
						writeln(rep,'Output Too Long');
						ends(0);
					end;
			ends(fsco);
	end.
//CEOI 2011 Day1 T1 balloons的SPJ的代碼 ( C++ 模板 )
#include<cstdio>
#include<cstdlib>
FILE *fscore,*freport,*fstd,*fin,*fout;
bool Judge()
{
    double x,y,dif;
    fscanf(fstd,"%lf",&x);
    fscanf(fout,"%lf",&y);
    dif=(x>y)?(x-y):(y-x);
    fprintf(freport,"Std:%.10lf\nYour Ans:%.10lf\nDiffer:%.10lf\n",x,y,dif);
    return dif<=0.000001;
}
int main(int argc,char *argv[])
{
    fscore=fopen("score.log","w");	//打開得分文件
    freport=fopen("report.log","w");//打開報告文件
    fstd=fopen(argv[2],"r");		//打開測試點標準輸出文件
    int score=atoi(argv[1]);		//取得測試點的分數

    fin=fopen("elephant.in","r");	//打開測試點標準輸入文件
    fout=fopen("elephant.out","r"); //打開用戶的數據輸出文件
    if (!fout)
    {
    	fprintf(fscore,"%d",0);		//返回0分
    	fprintf(freport,"no output");//報告Judge結果爲no output
    }
    else if (Judge())  //Judge後結果爲真
    {
        fprintf(fscore,"%d",score);//返回滿分
        fprintf(freport,"right");  //報告Judge結果爲right
    }
    else
    {
        fprintf(fscore,"%d",0);  //返回0分
        fprintf(freport,"wrong");//報告Judge結果爲wrong
    }

    fclose(fscore);//關閉得分文件
    fclose(freport);//關閉報告文件
    return 0;
}
實例演示:

1299. bplusa
☆   輸入文件:bplusa.in   輸出文件:bplusa.out   評測插件
【題目描述】
輸入一個整n,將其拆爲兩個非負整數a,b,使a,b的和等於n。
【輸入格式】
輸入數據只有一行,爲一個整數。
【輸出格式】
輸出數據只有一行,兩個整數,中間用一個空格隔開。
【樣例輸入】
5
【樣例輸出】
2 3
選手代碼:

#include<stdio.h>

int main()
{
	freopen("bplusa.in","r",stdin);
	freopen("bplusa.ans","w",stdout);
	int n;
	scanf("%d",&n);
	printf("1 %d",n-1);
	return 0;
}
Special Judge 代碼(評測插件)
#include<cstdio>
#include<cstdlib>
FILE *fscore,*freport,*fstd,*fin,*fout;
bool Judge()
{
	int n,x,y,dif;
	fscanf(fin,"%d",&n);
	fscanf(fout,"%d%d",&x,&y);
	dif=n==(x+y)?1:0;
	fprintf(freport,"Std:%d + :%d == n:%d\n",x,y,dif);
	return dif;
}
int main(int argc,char *argv[])
{
	fscore=fopen("score.log","w");	//打開得分文件
	freport=fopen("report.log","w");//打開報告文件
	fstd=fopen(argv[2],"r");		//打開測試點標準輸出文件
	int score=atoi(argv[1]);		//取得測試點的分數

	fin=fopen("bplusa.in","r");		//打開測試點標準輸入文件
	fout=fopen("bplusa.ans","r");	//打開用戶的數據輸出文件
	if (!fout)
	{
		fprintf(fscore,"%d",0);		//返回0分
		fprintf(freport,"no output");//報告Judge結果爲no output
	}
	else if (Judge())	//Judge後結果爲真
	{
		fprintf(fscore,"%d",score);	//返回滿分
		fprintf(freport,"right");	//報告Judge結果爲right
	}
	else
	{
		fprintf(fscore,"%d",0);//返回0分
		fprintf(freport,"wrong");//報告Judge結果爲wrong
	}

	fclose(fscore);		//關閉得分文件
	fclose(freport);	//關閉報告文件
	return 0;
}

CENA代碼評測軟件系列之一:簡介


發佈了194 篇原創文章 · 獲贊 457 · 訪問量 102萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章