更换自带对拍模式 - luosiwei-cmd/CarYon GitHub Wiki

更换自带对拍模式

什么叫做对拍模式呢?其实就是比较您的程序输出文件和标准程序输出文件的方案。

CarYon 提供了3种对拍模式:FULLtest,IOIStyleNOIPStyle

下面分别介绍3种比较方法。

NOIPStyleNOI 系列比赛采用的比较方法,其规定是过滤掉每一行末的一个空格和行尾的换行。其他的地方进行逐元素的比较。

下面提供 NOIPStyle 的源码供参考:

#include<bits/stdc++.h>
using namespace std;
#define UKE -1
#define AC 1
#define WA 0
int compareFile(FILE* file_compared, FILE* file_checked){
    bool diff=0;
    int N=65536;
    char b1[N],b2[N];
    size_t s1,s2;
    while(1){   
		if(fgets(b1,N,file_compared)==NULL||fgets(b2,N,file_checked)==NULL){
			break;
		}  
        s1=strlen(b1);
        s2=strlen(b2);
        if((s1!=s2&&s1+2!=s2&&s1-2!=s2&&s1+1!=s2&&s1-1!=s2)||memcmp(b1,b2,min(s1,s2)-1)){
            diff=1;
            break;
        }
    }
    free(b1);
    free(b2);
    if(diff)
		return 0;
    else 
		return 1;
}
int main(int argc,char* argv[]){
	if(argc<=2){
		return UKE;
	}
	FILE* fuser=fopen(argv[1],"r");
	FILE* fstd=fopen(argv[2],"r");
	if(compareFile(fuser,fstd)==1){
		return AC;
	}
	else {
		return WA;
	}
	return 0;
} 

FULLtest 是比较不常见的比较方法,一般用于对输出格式要求非常严格的场所,并且对换行和行末空格非常区分,这样的话会做出一些无意义的丢分,一般不建议使用。下面给出源码:

#include<bits/stdc++.h>
#include<ctime>
using namespace std;
#define UKE -1
#define AC 1
#define WA 0
int compareFile(FILE* file_compared, FILE* file_checked){
    bool diff = 0;
    int N = 65536;
    char* b1 = (char*) calloc (1, N+1);
    char* b2 = (char*) calloc (1, N+1);
    size_t s1, s2;

    do {
        s1= fread(b1,1, N, file_compared);
        s2 = fread(b2,1, N, file_checked);
        if ((s1!=s2)||memcmp(b1, b2, s1)) {
            diff = 1;
            break;
        }
    }while(!feof(file_compared)||!feof(file_checked));

    free(b1);
    free(b2);

    if (diff) return 0;
    else return 1;
}
int main(int argc,char* argv[]){
	if(argc<=2){
		return UKE;
	}
	FILE* fuser=fopen(argv[1],"r");
	FILE* fstd=fopen(argv[2],"r");
	if(compareFile(fuser,fstd)==1){
		return AC;
	}
	else {
		return WA;
	}
	return 0;
} 

IOIStyle 是平常 Online Judge 的评测方式,它不仅会像 NOIPStyle 一样过滤掉每行一个空格+文件末换行,还会给出错误的行,本应该是,而不是的评测消息。

IOIStyle 的特殊评测消息需要在 tools\Compare\IOI 文件夹中的 IOI.log 查看。

对于 WA 的评测点,两行,AC 则一行,您在此处 TLE 显示为 AC

若为 WA,则显示Wrong Answer On Row x, expected y, found z

AC/TLE 显示 Accept.

下面给出源码供参考:

#include<bits/stdc++.h>
using namespace std;
#define UKE -1
#define AC 1
#define WA 0
int cnt=1;
int compareFile(FILE* file_compared, FILE* file_checked){
    bool diff=0;
    int N=65536;
    char b1[N],b2[N];
    size_t s1,s2;
    while(1){
    	cnt++;
		if(fgets(b1,N,file_compared)==NULL||fgets(b2,N,file_checked)==NULL){
			break;
		}  
        s1=strlen(b1);
        s2=strlen(b2);
        if((s1!=s2&&s1+2!=s2&&s1-2!=s2&&s1+1!=s2&&s1-1!=s2)||memcmp(b1,b2,min(s1,s2)-1)){
            cerr<<"Wrong Answer On Row "<<cnt-1<<", expected "<<b1<<", found "<<b2;
			diff=1;
            break;
        }
    }
    free(b1);
    free(b2);
    if(diff)
		return 0;
    else 
		return 1;
}
int main(int argc,char* argv[]){
	if(argc<=2){
		return UKE;
	}
	FILE* fuser=fopen(argv[1],"r");
	FILE* fstd=fopen(argv[2],"r");
	system("mkdir IOI");
	freopen("IOI./IOI.log","w",stderr);
	if(compareFile(fuser,fstd)==1){
		cerr<<"Accept.\n";
		return AC;
	}
	else {
		return WA;
	}
	return 0;
} 

默认的比较器为 NOIPStyle,如果您需要更换比较器,您需要在caryon.h中搜索:

std::string command="tools\\Compare\\NOIPStyle.exe debug-"+dataname+"//"+dataname+Debug1+".ans data-"+dataname+"//"+dataname+Debug1+".out";

改为

std::string command="tools\\Compare\\FULLtest.exe debug-"+dataname+"//"+dataname+Debug1+".ans data-"+dataname+"//"+dataname+Debug1+".out";

或者

std::string command="tools\\Compare\\IOIStyle.exe debug-"+dataname+"//"+dataname+Debug1+".ans data-"+dataname+"//"+dataname+Debug1+".out";
⚠️ **GitHub.com Fallback** ⚠️