关于spj我想说

从 Trac 迁移的文章

这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。

原文章内容如下:

关于Special Judge的checker.cc写法: 

zz skatou 前辈的帖子 

如果你的题目有多解,还要有一个special judge。 
special judge可以读的文件有input,output,还有用户的输出文件,由命令行的第一个参数传入,C++就是args[1]。 
special judge成功运行并且返回0表示AC,如果程序crash掉或者返回不是0就不AC。 
给一个sample 

{{{
#!cpp
#include <cstdio> 
#include <cstdlib> 
#include <cstring> 
#include <algorithm> 
#include <iostream> 
#include <cmath> 
#include <string> 
#include <set> 
#include <map> 
#include <queue> 
#include <deque> 
#include <vector> 
#include <list> 
#include <sstream> 
#include <iterator> 
using namespace std; 

FILE* infile = 0; 
FILE* outfile = 0; 
FILE* ansfile = 0; 

void exit(char* msg, int exitCode) { 
    if (infile != 0) { 
        fclose(infile); 
    } 
    if (outfile != 0) { 
        fclose(outfile); 
    } 
    if (ansfile != 0) { 
        fclose(ansfile); 
    } 
    printf("%s\n", msg); 
    exit(exitCode); 
} 

void init(int argc, char* argv[]) { 
    if ((infile = fopen("input", "r")) == 0) { 
        exit("Cannot open input file", -1); 
    } 
    if ((outfile = fopen(argv[1], "r")) == 0) { 
        exit("Cannot open output file", -1); 
    } 
    if ((ansfile = fopen("output", "r")) == 0) { 
        exit("Cannot open answer file", -1); 
    } 
} 

bool u[110000], u2[110000]; 
int cnt, cnt2, tmp; 

int main(int argc, char* argv[]) { 
    if (argc != 2) { 
        exit("Usage: jscript ansfile", -1); 
    } 
    init(argc, argv); 
    while (fscanf(ansfile, "%d", &cnt) != EOF) { 
        fscanf(outfile, "%d", &cnt2); 
        if (cnt != cnt2) { 
            exit("Different key edge count", -1); 
        } 
        memset(u, false, sizeof(u)); 
        memset(u2, false, sizeof(u2)); 
        for (int i = 0; i < cnt; ++i) { 
            fscanf(ansfile, "%d", &tmp); 
            u[tmp - 1] = true; 
        } 
        for (int i = 0; i < cnt2; ++i) { 
            fscanf(outfile, "%d", &tmp); 
            u2[tmp - 1] = true; 
        } 
        for (int i = 0; i < cnt; ++i) if (u[i] != u2[i]) { 
            exit("Wrong answer", -1); 
        } 
    } 
    if (fscanf(outfile, "%d", &tmp) != EOF) { 
        exit("Redundant output", -1); 
    } 
    exit("Yes", 0); 
}
}}}

关于Special Judge的checker.cc写法:

zz skatou 前辈的帖子

如果你的题目有多解,还要有一个special judge。

special judge可以读的文件有input,output,还有用户的输出文件,由命令行的第一个参数传入,C++就是args[1]。

special judge成功运行并且返回0表示AC,如果程序crash掉或者返回不是0就不AC。

给一个sample

#include <cstdio> 
#include <cstdlib> 
#include <cstring> 
#include <algorithm> 
#include <iostream> 
#include <cmath> 
#include <string> 
#include <set> 
#include <map> 
#include <queue> 
#include <deque> 
#include <vector> 
#include <list> 
#include <sstream> 
#include <iterator> 
using namespace std; 
FILE* infile = 0; 
FILE* outfile = 0; 
FILE* ansfile = 0; 
void exit(char* msg, int exitCode) { 
    if (infile != 0) { 
        fclose(infile); 
    } 
    if (outfile != 0) { 
        fclose(outfile); 
    } 
    if (ansfile != 0) { 
        fclose(ansfile); 
    } 
    printf("%s\n", msg); 
    exit(exitCode); 
} 
void init(int argc, char* argv[]) { 
    if ((infile = fopen("input", "r")) == 0) { 
        exit("Cannot open input file", -1); 
    } 
    if ((outfile = fopen(argv[1], "r")) == 0) { 
        exit("Cannot open output file", -1); 
    } 
    if ((ansfile = fopen("output", "r")) == 0) { 
        exit("Cannot open answer file", -1); 
    } 
} 
bool u[110000], u2[110000]; 
int cnt, cnt2, tmp; 
int main(int argc, char* argv[]) { 
    if (argc != 2) { 
        exit("Usage: jscript ansfile", -1); 
    } 
    init(argc, argv); 
    while (fscanf(ansfile, "%d", &cnt) != EOF) { 
        fscanf(outfile, "%d", &cnt2); 
        if (cnt != cnt2) { 
            exit("Different key edge count", -1); 
        } 
        memset(u, false, sizeof(u)); 
        memset(u2, false, sizeof(u2)); 
        for (int i = 0; i < cnt; ++i) { 
            fscanf(ansfile, "%d", &tmp); 
            u[tmp - 1] = true; 
        } 
        for (int i = 0; i < cnt2; ++i) { 
            fscanf(outfile, "%d", &tmp); 
            u2[tmp - 1] = true; 
        } 
        for (int i = 0; i < cnt; ++i) if (u[i] != u2[i]) { 
            exit("Wrong answer", -1); 
        } 
    } 
    if (fscanf(outfile, "%d", &tmp) != EOF) { 
        exit("Redundant output", -1); 
    } 
    exit("Yes", 0); 
}