增加题目OI排行榜得分 与总得分区别

This commit is contained in:
Himit_ZH 2021-08-07 22:57:07 +08:00
parent 065efcf317
commit bea8b7b42f
11 changed files with 67 additions and 17 deletions

View File

@ -20,6 +20,8 @@ Github仓库地址[https://github.com/HimitZH/HOJ](https://github.com/HimitZH
Gitee仓库地址[https://gitee.com/himitzh0730/hoj](https://gitee.com/himitzh0730/hoj)
**注意:**建议使用Centos8以上或Ubuntu16.04以上的操作系统不然judgeserver可能无法正常启动。
**有任何部署问题或项目bug请发issue或者加QQ群598587305进行咨询。**
**如果要对本项目进行商业化请在页面底部的Powered by指向HOJ本仓库地址顺便点上star收藏本项目对开发者的支持谢谢。**

View File

@ -3,7 +3,7 @@
<mapper namespace="top.hcode.hoj.dao.JudgeMapper">
<select id="getCommonJudgeList" resultType="top.hcode.hoj.pojo.vo.JudgeVo" useCache="false">
select j.uid,j.submit_id,j.submit_time,j.uid,j.username,j.uid,j.pid,j.status,j.share,
j.time,j.memory,j.score,j.length,j.language,j.cid,j.cpid,j.judger,p.problem_id as display_pid,p.title
j.time,j.memory,j.score,j.oi_rank_score,j.length,j.language,j.cid,j.cpid,j.judger,p.problem_id as display_pid,p.title
from judge j,problem p
<where>
p.id = j.pid AND j.cid = 0 AND j.cpid = 0

View File

@ -38,7 +38,7 @@
FROM user_info ui, (
SELECT u.uuid AS uid, COALESCE(SUM(s.score),0) AS score
FROM user_info u, (
SELECT MAX(score) AS score, uid, pid
SELECT MAX(oi_rank_score) AS score, uid, pid
FROM judge
WHERE cid=0
GROUP BY pid, uid
@ -74,7 +74,7 @@
<!-- 子查询-->
<select id="getProblemScore" resultType="java.lang.Integer">
SELECT MAX(score) AS sum_score FROM judge
SELECT MAX(oi_rank_score) AS sum_score FROM judge
WHERE uid=#{uid} AND cid=0 AND score IS NOT NULL GROUP BY pid
</select>

View File

@ -57,6 +57,9 @@ public class JudgeVo {
@ApiModelProperty(value = "题目得分ACM题目默认为null")
private Integer score;
@ApiModelProperty(value = "该题在OI排行榜的分数")
private Integer oiRankScore;
@ApiModelProperty(value = "代码长度")
private Integer length;

View File

@ -55,13 +55,13 @@ public class JudgeStrategy {
// 对用户源代码进行编译 获取tmpfs中的fileId
userFileId = Compiler.compile(Constants.CompileConfig.getCompilerByLanguage(judge.getLanguage()), judge.getCode(), judge.getLanguage());
// 测试数据文件所在文件夹
String testCasesDir = Constants.JudgeDir.TEST_CASE_DIR.getContent() +File.separator+"problem_" + problem.getId();
String testCasesDir = Constants.JudgeDir.TEST_CASE_DIR.getContent() + File.separator + "problem_" + problem.getId();
// 从文件中加载测试数据json
JSONObject testCasesInfo = problemTestCaseUtils.loadTestCaseInfo(problem.getId(), testCasesDir, problem.getCaseVersion(), !StringUtils.isEmpty(problem.getSpjCode()));
JSONArray testcaseList = (JSONArray) testCasesInfo.get("testCases");
String version = testCasesInfo.getStr("version");
// 检查是否为spj同时是否有spj编译完成的文件若不存在就先编译生成该spj文件同时也要检查版本
Boolean hasSpjOrNotSpj = checkOrCompileSpj(problem,version);
Boolean hasSpjOrNotSpj = checkOrCompileSpj(problem, version);
// 如果该题为spj但是没有spj程序
if (!hasSpjOrNotSpj) {
result.put("code", Constants.Judge.STATUS_SYSTEM_ERROR.getStatus());
@ -133,7 +133,7 @@ public class JudgeStrategy {
}
public Boolean checkOrCompileSpj(Problem problem,String version) throws CompileError, SystemError {
public Boolean checkOrCompileSpj(Problem problem, String version) throws CompileError, SystemError {
// 如果是需要特判的题目则需要检测特批程序是否已经编译否则进行编译
if (!StringUtils.isEmpty(problem.getSpjCode()) || !problem.getCaseVersion().equals(version)) {
Constants.CompileConfig spjCompiler = Constants.CompileConfig.getCompilerByLanguage(problem.getSpjLanguage());
@ -146,7 +146,8 @@ public class JudgeStrategy {
}
// 获取判题的运行时间运行空间OI得分
public HashMap<String, Object> computeResultInfo(List<JudgeCase> allTestCaseResultList, Boolean isACM, Integer errorCaseNum, Integer totalScore) {
public HashMap<String, Object> computeResultInfo(List<JudgeCase> allTestCaseResultList, Boolean isACM,
Integer errorCaseNum, Integer totalScore, Integer problemDiffculty) {
HashMap<String, Object> result = new HashMap<>();
// 用时和内存占用保存为多个测试点中最长的
allTestCaseResultList.stream().max(Comparator.comparing(t -> t.getTime()))
@ -157,15 +158,20 @@ public class JudgeStrategy {
// OI题目计算得分
if (!isACM) {
// 全对的直接用总分
// 全对的直接用总分*0.1+2*题目难度
if (errorCaseNum == 0) {
int oiRankScore = (int) Math.round(totalScore * 0.1 + 2 * problemDiffculty);
result.put("score", totalScore);
result.put("oiRankScore", oiRankScore);
} else {
int score = 0;
for (JudgeCase testcaseResult : allTestCaseResultList) {
score += testcaseResult.getScore();
}
//测试点总得分*0.1+2*题目难度*测试点总得分/题目总分
int oiRankScore = (int) Math.round(score * 0.1 + 2 * problemDiffculty * (score * 1.0 / totalScore));
result.put("score", score);
result.put("oiRankScore", oiRankScore);
}
}
return result;
@ -185,7 +191,7 @@ public class JudgeStrategy {
Integer time = jsonObject.getLong("time").intValue();
Integer memory = jsonObject.getLong("memory").intValue();
Integer status = jsonObject.getInt("status");
Long caseId = jsonObject.getLong("caseId",null);
Long caseId = jsonObject.getLong("caseId", null);
String inputFileName = jsonObject.getStr("inputFileName");
String outputFileName = jsonObject.getStr("outputFileName");
JudgeCase judgeCase = new JudgeCase();
@ -218,7 +224,8 @@ public class JudgeStrategy {
}
// 获取判题的运行时间运行空间OI得分
HashMap<String, Object> result = computeResultInfo(allCaseResList, isACM, errorTestCaseList.size(), problem.getIoScore());
HashMap<String, Object> result = computeResultInfo(allCaseResList, isACM, errorTestCaseList.size(),
problem.getIoScore(), problem.getDifficulty());
// 如果该题为ACM类型的题目多个测试点全部正确则AC否则取第一个错误的测试点的状态
// 如果该题为OI类型的题目, 若多个测试点全部正确则AC若全部错误则取第一个错误测试点状态否则为部分正确

View File

@ -74,6 +74,8 @@ public class JudgeServiceImpl extends ServiceImpl<JudgeMapper, Judge> implements
judge.setTime(Math.min(time, problem.getTimeLimit()));
// score
judge.setScore((Integer) judgeResult.getOrDefault("score", null));
// oi_rank_score
judge.setOiRankScore((Integer) judgeResult.getOrDefault("oiRankScore", null));
return judge;
}

View File

@ -89,6 +89,9 @@ public class Judge implements Serializable {
@TableField(fill = FieldFill.INSERT)
private Integer version;
@TableField(value = "该题在OI排行榜的分数")
private Integer oiRankScore;
@TableField(fill = FieldFill.INSERT)
private Date gmtCreate;

View File

@ -226,6 +226,9 @@ export const m = {
Enter_Author:'Enter Author',
Run_ID:'Run ID',
Problem:'Problem',
Problem_Score:'Problem Score',
OI_Rank_Score:'OI Rank Score',
OI_Rank_Calculation_Rule:'OI Rank Calculation Rule',
// /views/oj/status/SubmissionDetails.vue
Test_point_details:'Test point details',

View File

@ -228,6 +228,10 @@ export const m = {
Enter_Author:'请输入作者',
Run_ID:'Run ID',
Problem:'题目',
Problem_Score:'OI题目总得分',
OI_Rank_Score:'OI排行榜得分',
OI_Rank_Calculation_Rule:'OI排行得分计算公式',
// /views/oj/status/SubmissionDetails.vue
Test_point_details:'测试点详情',

View File

@ -97,7 +97,19 @@
v-if="isIOProblem"
>
<template v-slot="{ row }">
<span>{{ row.score }}</span>
<el-tooltip placement="top">
<div slot="content">
{{ $t('m.Problem_Score') }}{{
row.score != null ? row.score : $t('m.Unknown')
}}<br />{{ $t('m.OI_Rank_Score') }}{{
row.oiRankScore != null ? row.oiRankScore : $t('m.Unknown')
}}<br />
{{
$t('m.OI_Rank_Calculation_Rule')
}}:(score*0.1+diffculty*2)*(ac_testcase/sum_testcase)
</div>
<span>{{ row.score }}</span>
</el-tooltip>
</template>
</vxe-table-column>
<vxe-table-column :title="$t('m.Length')" min-width="80">

View File

@ -159,12 +159,26 @@
<vxe-table-column field="score" :title="$t('m.Score')" width="64">
<template v-slot="{ row }">
<template v-if="row.score != null">
<el-tag
effect="plain"
size="medium"
:type="JUDGE_STATUS[row.status]['type']"
>{{ row.score }}</el-tag
>
<el-tooltip placement="top">
<div slot="content">
{{ $t('m.Problem_Score') }}{{
row.score != null ? row.score : $t('m.Unknown')
}}<br />{{ $t('m.OI_Rank_Score') }}{{
row.oiRankScore != null
? row.oiRankScore
: $t('m.Unknown')
}}<br />
{{
$t('m.OI_Rank_Calculation_Rule')
}}:(score*0.1+diffculty*2)*(ac_testcase/sum_testcase)
</div>
<el-tag
effect="plain"
size="medium"
:type="JUDGE_STATUS[row.status]['type']"
>{{ row.score }}</el-tag
>
</el-tooltip>
</template>
<template
v-else-if="