常见问题及解答

  1. 比赛赛制有哪些?各个赛制分别有何特点?
    目前赛制有三种:
    OI
    在OI赛制下,比赛时选手提交代码的评测结果不可见,他人提交的代码不可见,实时排名亦不可见。 当比赛结束后,会公布比赛排名、所有选手代码和所有提交记录评测结果。 题目有部分分,选手相应题目的得分按照他最后一次提交的评测结果不是“编译失败”的记录的得分计算。
    ACM/ICPC
    在ACM/ICPC赛制下,比赛时可查看自己提交的代码的评测结果,也可随时观看实时排名,但无法查看他人代码。 当比赛结束后,会公布所有人的代码与评测结果。 题目只有通过/不通过两种结果,没有部分分。 当选手提交某题代码超过一次时,会产生一定的罚时。 最终排名以通过题目数为第一关键字,罚时为第二关键字的方式计算。
    Codeforces
    在Codeforces赛制下,测试数据分为pretest和finaltest,题目分数动态计算(随时间的推移而减少),所有记录评测情况公开,实时排名公开。 当用户提交时,会立即测试pretest部分,并显示评测结果。 选手通过某题的pretest后,就可以将自己相应题目的代码锁定(锁定后不可再次提交此题代码)。 锁定代码后,选手可以查看他人对此题提交的代码。 如果选手认为他人已通过pretest的代码存在错误,可以制造测试数据对其进行猎杀。 猎杀成功,选手自己的得分会提升,他人的提交记录算作错误,且不能再次被猎杀;猎杀失败,选手自己的得分会下降。 最终选手对于某题的得分,是他通过finaltest的记录提交时相应题目的动态分,加上他由于猎杀成功或失败得到或失去的得分。
  2. 系统评测环境、各语言编译命令、堆栈大小是多少?
    评测在 Linux 下进行,C/C++代码请使用cin、cout或 %lld 来输入输出64位整数。
    • C++编译命令:g++ -O2 -lm --std=c++11 -o a.out -DONLINE_JUDGE -fno-asm code.cpp
    • C编译命令:gcc -O2 -lm --std=c99 -o a.out -DONLINE_JUDGE -fno-asm code.c
    • Pascal编译命令:fpc -O2 -dONLINE_JUDGE code.pas
    系统栈大小为 min(内存限制, 256MB)
  3. 程序运行时间是如何计算的?
    一般来讲,一个程序的运行时间主要分为三种:
    1. 实际运行时间
    2. 用户态运行时间
    3. 内核态运行时间
    目测,ContestHunter使用的AllKorrect评测机根据如下的规则判断程序的运行时间:
    1. 如果您的用户态时间超过了时间限制,则判定为TLE
    2. 如果您的实际时间严重超过了时间限制,即使您的用户态时间没有超出限制,程序也会被判断为TLE
    3. 不符合以上两条,则您的程序没有TLE,且运行时间按用户态运行时间计算。
  4. 比赛申办有何注意事项?
    Contest Hunter 公开赛举办与审核要求

    提交审核前必须完成的工作:
    (1)提供所有题目的简化版描述(裸模型);
    (2)提供所有题目的题解(叙述所考察算法及解题思路)和标程
    注1:若题目非原创,请提供来源;
    注2:非传统型题目同样需要提供所有测试点的解题方案。

    将简化版描述、题解各制成一份pdf,与标程一起打包发至lydrainbowcat@pku.edu.cn
    发送后CH将安排验题,验题工作一般在3天内完成(无特殊情况最多一周)。
    题目初审通过后CH将通知并协助出题人进行下一阶段的工作。

    注3:(能力排名在2000以上 || 获得或入选过 ((NOI金牌 && 集训队) || ACM-ICPC世界总决赛)) 的出题人免审。

    比赛开放报名前必须完成的工作:
    (1)上传题目描述、数据
    (2)将标程在CH上测试通过
    (3)每道题目至少提交一道暴力程序用于检验;
    (4)与CH讨论确定比赛时间,一般要求比赛时间不超过5小时,每周比赛不超过2次。
    如数据过大上传困难,可以联系管理员协助;
    上述工作完成后比赛将正式挂出开放报名。

    比赛开始前必须完成的工作:
    (1)比赛开始2天前完善题目的完整版描述(例如可添加背景等);
    (2)比赛开始1~2天前发送一次邀请邮件。
    可做其它适当的宣传。

    比赛中必须进行的工作:
    (1)全程关注比赛进程,解答疑问

    建议(不必须)进行的工作:
    (1)OI赛制每题至少3档部分分,每档部分分提交一个程序以检验可以拿到对应分值;

    Unofficial公开赛的回归:
    CH的比赛将分为三档:Official公开赛(计入能力排名)、Unofficial公开赛(不计入能力排名)、小组赛
    公开赛一律需要审核,小组赛(Unofficial自由比赛区)免审核;
    在第1步中初审失败的公开赛,出题人不愿意修改或者修改2次后仍审核失败的,将举办Unofficial公开赛。

  5. 标程应该如何编写?
    标程应该首先从标准输入中读取数据,然后向标准输出中输出正确答案。
    对于Codeforces赛制的标程,应当在读入数据后首先检查数据是否合法,如果数据有问题,标程应当立即返回1并结束(C++中的main函数return 1;)。
    例如判断是否超出数据范围:if(n<1||n>10000) return 1;
    如果数据没有问题,标程应输出正确答案,并返回0。
  6. 比较器如何编写?
    注意:您可以将比较器一栏留空,这样会使用预置的默认比较器,它可以支持忽略文末换行符和行末空格后的全文比较
    命令行有三个参数,依次为标准输出选手输出标准输入文件名
    比较器返回0代表程序正确,返回1代表程序错误。其他情况均视为比较器内部错误。
    这是系统预置的默认比较器:
    #include <cassert>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    
    //一些定义
    const int ACCEPT = 0;
    const int WRONG_ANSWER = 1;
    //fstd 标准输出 fout 选手输出 fin 标准输入
    FILE *fstd,*fout,*fin;
    
    int LastCharStd = -2,LastCharOut=-2;
    
    //检查下一个字符
    inline int Peek(FILE* f){
        if(f==fstd){
            if(LastCharStd == -2)
                LastCharStd=fgetc(f);
            return LastCharStd;
        }else{
            if(LastCharOut == -2)
                LastCharOut=fgetc(f);
            return LastCharOut;
        }
    }
    
    //取出下一个字符
    inline void Pop(FILE* f){
        if(f==fstd){
            if(LastCharStd == -2)
                fgetc(f);
            else
                LastCharStd = -2;
        }else{
            if(LastCharOut == -2)
                fgetc(f);
            else
                LastCharOut = -2;
        }
    }
    
    //判断字符是否为空白
    inline bool IsSpace(int ch){
        return ch>=0 && (ch<=32 || ch>=127);
    }
    
    //执行比较操作。
    bool DoCompare(){
        int stdPosition=0,outPosition=0;
        bool stdInSpace=true,outInSpace=true;
        while(true){
            int stdC=Peek(fstd),outC=Peek(fout);
            if(stdC==EOF && outC==EOF){
                return true;
            }else if(stdC==EOF && IsSpace(outC)){
                outPosition++;
                Pop(fout);
            }else if(outC==EOF && IsSpace(stdC)){
                stdPosition++;
                Pop(fstd);
            }else if(IsSpace(stdC) && IsSpace(outC)){
                stdPosition++;
                outPosition++;
                stdInSpace=true;
                outInSpace=true;
                Pop(fstd);
                Pop(fout);
            }else if(IsSpace(stdC) && outInSpace){
                stdPosition++;
                Pop(fstd);
            }else if(IsSpace(outC) && stdInSpace){
                outPosition++;
                Pop(fout);
            }else if(stdC==outC){
                stdPosition++;
                outPosition++;
                stdInSpace=false;
                outInSpace=false;
                Pop(fstd);
                Pop(fout);
            }else{
                printf("答案文件的第%d字节",stdPosition+1);
                if(stdC==EOF){
                    printf("<EOF>");
                }else{
                    printf("0x%x",stdC);
                }
                printf("不能匹配输出文件的第%d字节",outPosition+1);
                if(outC==EOF){
                    printf("%lt;EOF%gt;");
                }else{
                    printf("0x%x",outC);
                }
                puts("");
                return false;
            }
        }
    }
    
    int main(int argc, char* argv[])
    {
        if(argc!=4){
            printf("参数不足 %d",argc);
            return -1;
        }
    
        //打开文件
        if(NULL==(fstd=fopen(argv[1],"r"))){
            return -1;
        }
        if(NULL==(fout=fopen(argv[2],"r"))){
            return -1;
        }
        if(NULL==(fin=fopen(argv[3],"r"))){
            return -1;
        }
    
        if(DoCompare()){
            return ACCEPT;
        }else{
            return WRONG_ANSWER;
        }
    }