以下是用chatgpt提供的IOI(OFS)赛制的代码!


const ioiObjectiveFirstSubmit = buildContestRule({
    TEXT: 'IOI(ObjectiveFirstSubmit)',
    submitAfterAccept: false, // 提交之后立即出结果
    showScoreboard: (tdoc, now) => now > tdoc.endAt,
    showSelfRecord: (tdoc, now) => now > tdoc.endAt,
    showRecord: (tdoc, now) => now > tdoc.endAt && !isLocked(tdoc),

    // 统计提交情况
    stat(tdoc, journal) {
        const display: Record<number, OiDetail> = {};
        const detail: Record<number, OiDetail> = {};
        const accepted: Record<number, boolean> = {};
        let score = 0;

        const lockAt = isLocked(tdoc) ? tdoc.lockAt : null;

        for (const j of journal.filter((i) => tdoc.pids.includes(i.pid))) {
            // 跳过已锁定的提交
            if (lockAt && j.rid.getTimestamp() > lockAt) continue;

            // 记录第一次接受的提交
            if (!accepted[j.pid]) {
                accepted[j.pid] = true; // 标记为已接受
                detail[j.pid] = j; // 记录提交细节
                display[j.pid] ||= {}; 
                display[j.pid] = j; // 显示提交的分数
            }
        }

        // 计算总分
        for (const i in display) {
            score += ((tdoc.score?.[i] || 100) * (display[i].score || 0)) / 100;
        }

        return { score, detail, display };
    },

    async scoreboardHeader(config, _, tdoc, pdict) {
        const columns: ScoreboardNode[] = [
            { type: 'rank', value: '#' },
            { type: 'user', value: _('User') },
        ];

        if (config.isExport && config.showDisplayName) {
            columns.push({ type: 'email', value: _('Email') });
            columns.push({ type: 'string', value: _('School') });
            columns.push({ type: 'string', value: _('Name') });
            columns.push({ type: 'string', value: _('Student ID') });
        }

        columns.push({ type: 'total_score', value: _('Total Score') });

        for (let i = 1; i <= tdoc.pids.length; i++) {
            const pid = tdoc.pids[i - 1];
            pdict[pid].nAccept = pdict[pid].nSubmit = 0;
            if (config.isExport) {
                columns.push({
                    type: 'string',
                    value: '#{0} {1}'.format(i, pdict[pid].title),
                });
            } else {
                columns.push({
                    type: 'problem',
                    value: String.fromCharCode(65 + i - 1),
                    raw: pid,
                });
            }
        }
        return columns;
    },

    async scoreboardRow(config, _, tdoc, pdict, udoc, rank, tsdoc) {
        const row: ScoreboardNode[] = [
            { type: 'rank', value: rank.toString() },
            { type: 'user', value: udoc.uname, raw: tsdoc.uid },
        ];

        if (config.isExport && config.showDisplayName) {
            row.push({ type: 'email', value: udoc.mail });
            row.push({ type: 'string', value: udoc.school || '' });
            row.push({ type: 'string', value: udoc.displayName || '' });
            row.push({ type: 'string', value: udoc.studentId || '' });
        }

        row.push({ type: 'total_score', value: tsdoc.score || 0 });

        const tsddict = tsdoc.display || {};
        for (const pid of tdoc.pids) {
            const doc = tsddict[pid] || {} as Partial<OiDetail>;
            const colScore = doc.score ? doc.score : 0;
            row.push({
                type: 'record',
                value: colScore.toString(),
                raw: doc.rid,
                score: colScore,
            });
        }

        return row;
    },

    async scoreboard(config, _, tdoc, pdict, cursor) {
        const rankedTsdocs = await db.ranked(cursor, (a, b) => b.score - a.score); // 按分数降序排列
        const uids = rankedTsdocs.map(([, tsdoc]) => tsdoc.uid);
        const udict = await user.getListForRender(tdoc.domainId, uids, config.showDisplayName ? ['displayName'] : []);

        const columns = await this.scoreboardHeader(config, _, tdoc, pdict);
        const rows: ScoreboardRow[] = [
            columns,
            ...await Promise.all(rankedTsdocs.map(
                ([rank, tsdoc]) => this.scoreboardRow(
                    config, _, tdoc, pdict, udict[tsdoc.uid], rank, tsdoc,
                ),
            )),
        ];
        return [rows, udict];
    },

    async ranked(tdoc, cursor) {
        return await db.ranked(cursor, (a, b) => b.score - a.score); // 按分数降序排列
    },

    applyProjection(tdoc, rdoc) {
        if (isDone(tdoc)) return rdoc;
        delete rdoc.time;
        delete rdoc.memory;
        rdoc.testCases = [];
        rdoc.judgeTexts = [];
        delete rdoc.subtasks;
        delete rdoc.score;
        return rdoc;
    },
});


以下是用HTML写的IOI(OFS)赛制的代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>IOI Objective First Submit</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 20px;
        }
        .result {
            margin-top: 10px;
            font-weight: bold;
        }
    </style>
</head>
<body>
    <h1>IOI (Objective First Submit) Code Submission</h1>

    <!-- 提交代码的表单 -->
    <form id="submitForm">
        <label for="participant">Participant Name:</label>
        <input type="text" id="participant" required><br><br>

        <label for="code">Code Submission:</label><br>
        <textarea id="code" rows="10" cols="50" placeholder="Write your code here..." required></textarea><br><br>

        <button type="submit">Submit Code</button>
    </form>

    <!-- 评测结果 -->
    <div id="result" class="result"></div>

    <script>
        // 存储提交状态的哈希表
        const submissions = {};

        // 评测代码的简单逻辑(检查是否包含 'main' 函数)
        function evaluateCode(code) {
            return code.includes("main");
        }

        // 处理表单提交
        document.getElementById('submitForm').addEventListener('submit', function(event) {
            event.preventDefault();

            const participant = document.getElementById('participant').value.trim();
            const code = document.getElementById('code').value.trim();
            const resultDiv = document.getElementById('result');

            // 检查是否已经提交过代码
            if (submissions[participant]) {
                resultDiv.innerHTML = `Participant <b>${participant}</b> has already submitted code. No further submissions allowed.`;
            } else {
                // 记录第一次提交
                submissions[participant] = true;

                // 评测代码
                if (evaluateCode(code)) {
                    resultDiv.innerHTML = `Participant <b>${participant}</b> passed the evaluation!`;
                } else {
                    resultDiv.innerHTML = `Participant <b>${participant}</b> failed the evaluation.`;
                }
            }
        });
    </script>
</body>
</html>

5 条评论

  • 1