学习一个Cena和Lemon的SPJ

来源:互联网 发布:手机捉鬼软件 编辑:程序博客网 时间:2024/06/18 14:37

对于当正确的输出结果不唯一的时候,我们就需要使用自定义校验器们,也就是我们常说的Special Judge。一般来说我们需要自己编写Special Judge的判断程序,不同的评测系统对于Special Judge的要求也不一样,下面就来谈一谈Cena和Lemon的Special Judge。

Cena

首先,Cena的帮助里面是这样说的:

3.2.2 自定义校验器说明
获取必要的信息
待测的测试点的最高分 ParamStr(1)(Pascal) 或 argv1
标准输出文件名 ParamStr(2)(Pascal) 或 argv2
标准输入和选手输出同数据配置。
结果返回
得分返回文件 score.log 只有一行,为这个测试点的得分。可使用小数。
返回校验信息 report.log 若没有此文件,或此文件的内容为空,则没有校验信息,反之则将在评测结果右侧显示“(?)”,点击则显示信息。(参见: 查看评测结果)。
交互单元
本评测系统提供了编写校验程序的交互单元,以方便使用 Pascal 语言编写自定义校验程序。
libcheck.pas(位置:安装路径\lib) 说明如下:
变量:

std: Text;                        { 用于读取标准输出文件 }rep: Text;                        { 用于写入校验信息 }fso: Double;                      { 为这个测试点的满分 }

过程:

procedure Score(AScore: Double);  { 用于向评测系统报告得分 }procedure Finish;                 { 结束 }

使用举例 (Pascal语言):

uses  libcheck;var  a,b,c,stc: integer;begin  assign(input, 'add.in'); { 试题的输入文件名 }  reset(input);  readln(a, b);  close(input);  assign(input, 'add.out'); { 试题的输出文件名,由选手程序输出 }  reset(input);  readln(c);  close(input);  read(std,stc); { 从标准输出文件中读取标准答案 }  writeln(rep,'这个测试点的输入为:',a,' ',b);  writeln(rep,'标准输出为:',stc);  writeln(rep,'选手输出为:',c);  if stc=c then begin    writeln(rep, '正确。');    Score(fso); { 得满分 }  end  else begin    writeln(rep, '错误。');    Score(0); { 得 0 分 }  end;  writeln(rep, '本自定义校验程序由 *** 提供。仅供示例。');  Finish;end;

建议
请使用 32 位编译器(如 Free Pascal, Delphi, GCC )来编译您的校验程序,以加快评测的速度。

简单地来说,就是:

“score.log” 输出最终得分“report.log”输出错误报告#FILENAME.in”输入文件#FILENAME.out”选手输出文件argv[2]:标准输出文件argv[1]:单测试点分值

下面是一个我用的板子

#include<cstdio>  #include<cstdlib>  #include<cmath>FILE *fscore,*freport,*fstd,*fin,*fout;  int Judge()  {      fscanf(fstd,/*******/);    fscanf(fout,/*******/);    //judge函数}  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("circle.in","r");   //打开测试点标准输入文件      fout=fopen("circle.out","r"); //打开用户的数据输出文件      if (!fout)      {          fprintf(fscore,"%d",0);     //返回0分          fprintf(freport,"没输出你交上来干啥");//报告Judge结果为no output      }      else if (Judge()==1)  //Judge后结果为真      {          fprintf(fscore,"%d",score);//返回满分          fprintf(freport,"太厉害了,被你A了");  //报告Judge结果为right      }      /*部分分    else if (Judge()==-1)       {          fprintf(fscore,"%d",score<<1);//返回部分分          fprintf(freport,"你可能被卡精度了");      }    */    else  if (Judge()==0)    {          fprintf(fscore,"%d",0);  //返回0分          fprintf(freport,"你愉快地WA了");//报告Judge结果为wrong      }      fclose(fscore);//关闭得分文件      fclose(freport);//关闭报告文件      return 0;  }  

写好之后我们只需要把SPJ程序放到Data文件下,注意一定要运行生成exe文件。
然后把比较方式换成使用自定义校验器
然后就可以了

Lemon

这个我也不是很熟悉

所有的都从argv[]里面读入argv[1]:输入文件argv[2]:选手输出文件argv[3]:标准输出文件argv[4]:单个测试点分值argv[5]:输出最终得分的文件argv[6]:输出错误报告的文件

然后lemon的spj就大概这样写

int main(int argc,char *argv[]){    fin.open(argv[1]);    fout.open(argv[2]);    fstd.open(argv[3]);    fscore.open(argv[5]);    freport.open(argv[6]);    int score=atoi(argv[4]);    fscore<<score*Judge()<<endl;    fin.close();    fout.close();    fstd.close();    fscore.close();    freport.close();    retur