学习一个Cena和Lemon的SPJ

对于当正确的输出结果不唯一的时候,我们就需要使用自定义校验器们,也就是我们常说的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
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值