它是開放源程序的信息學競賽評測系統,能滿足大多數程序設計競賽的測評需求。
特色功能:
通過局域網自動收取選手程序。
高效率的數據文件配置工具。
自動選用對應的編譯器來編譯選手程序,也能使用解釋器或直接評測可執行文件。
能準確測出選手程序的運行時間和內存使用量,並可加入對運行時間和內存使用的限制。
自動比較選手程序的輸出和標準輸出的差異,並能將兩者出現差異的具體位置告訴評測者。
支持使用自定義校驗器,可評測有多解的試題。
可對評測結果進行統計分析。
可將評測結果以各種樣式打印或導出。
注意事項:
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;
}
實例演示:
輸入一個整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;
}