mirror of
https://github.com/renbaoshuo/S2OJ.git
synced 2024-11-22 13:28:41 +00:00
移除官方版本文档和题目示例
This commit is contained in:
parent
a0ac25e42e
commit
949ef0e573
1
docs/.gitignore
vendored
1
docs/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
site/
|
|
@ -1,4 +0,0 @@
|
|||||||
# 关于
|
|
||||||
文档编写:vfleaking
|
|
||||||
|
|
||||||
邮件:vfleaking@163.com
|
|
@ -1,3 +0,0 @@
|
|||||||
# 比赛
|
|
||||||
|
|
||||||
<p style="font-size:233px">坑</p>
|
|
@ -1,50 +0,0 @@
|
|||||||
# 开发
|
|
||||||
听说你想写代码?
|
|
||||||
|
|
||||||
svn://local\_uoj.ac/uoj 和 svn://local\_uoj.ac/judge_client 欢迎你(如果你没改 UOJ 的 hostname 的话),这是两个 svn 仓库,至于 svn 仓库权限问题……你需要手工加一下……
|
|
||||||
|
|
||||||
在 /var/svn/uoj/conf/passwd 这个文件中你可以加一行
|
|
||||||
<pre>
|
|
||||||
uoj = 666666
|
|
||||||
</pre>
|
|
||||||
来增加一位名为 "<samp>uoj</samp>",密码为 "<samp>666666</samp>" 的 svn 仓库管理员。
|
|
||||||
|
|
||||||
之后你就可以随意用 svn 玩耍了哇咔咔……
|
|
||||||
|
|
||||||
在本地写完之后,如果你想与别人分享,你可以把代码再放到 git 中(什么鬼?)再 push 到 github。
|
|
||||||
|
|
||||||
如果你想更新的东西已经不局限于网站代码,还想对数据库、文件系统之类的折腾一番,请在 app/upgrade 目录下建立文件夹,举个例子,叫 `2333_create_table_qaq`。即,以一串数字开头,后面加一个下划线,再后面随便取名字吧,仅能包含数字字母和下划线。
|
|
||||||
|
|
||||||
在这个文件夹下你可以放一些小脚本。大概 UOJ 运行这些小脚本是这么个逻辑:
|
|
||||||
```php
|
|
||||||
if (is_file("{$dir}/upgrade.php")) {
|
|
||||||
$fun = include "{$dir}/upgrade.php";
|
|
||||||
$fun("up");
|
|
||||||
}
|
|
||||||
if (is_file("{$dir}/up.sql")) {
|
|
||||||
runSQL("{$dir}/up.sql");
|
|
||||||
}
|
|
||||||
if (is_file("{$dir}/upgrade.sh")) {
|
|
||||||
runShell("/bin/bash {$dir}/upgrade.sh up");
|
|
||||||
}
|
|
||||||
```
|
|
||||||
你只需要在 /var/www/uoj/app 下执行 `php cli.php upgrade:up 2333_create_table_qaq` 就可以运行了,这个运行过程我们称为 `up`。
|
|
||||||
|
|
||||||
请务必再写一下还原的小脚本,我们称为 `down`。写完代码后你需要保证 `up` 再 `down` 能回到原来的系统。与 `up` 类似,你需要执行 `php cli.php upgrade:down 2333_create_table_qaq`,执行 `down` 的逻辑如下:
|
|
||||||
```php
|
|
||||||
if (is_file("{$dir}/upgrade.php")) {
|
|
||||||
$fun = include "{$dir}/upgrade.php";
|
|
||||||
$fun("down");
|
|
||||||
}
|
|
||||||
if (is_file("{$dir}/down.sql")) {
|
|
||||||
runSQL("{$dir}/down.sql");
|
|
||||||
}
|
|
||||||
if (is_file("{$dir}/upgrade.sh")) {
|
|
||||||
runShell("/bin/bash {$dir}/upgrade.sh down");
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
在数据库中,UOJ 会记录自己已经加载了哪些 upgrade,当你执行 `php cli.php upgrade:latest` 的时候,UOJ 会把所有已经在 app/upgrade 文件夹下但还没有加载的 upgrade 都给 `up` 一下,并且是按前缀上的那一串数字从小到大执行。所以写好了这种小 upgrade 之后,你就可以跟别人分享了!
|
|
||||||
|
|
||||||
不过关于架构什么的介绍我还是先
|
|
||||||
<p style="font-size:233px">坑着</p>
|
|
@ -1,4 +0,0 @@
|
|||||||
.hljs-preprocessor .hljs-keyword {
|
|
||||||
color: #999;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
# 概述
|
|
||||||
|
|
||||||
写点 UOJ 的文档方便大家。
|
|
||||||
|
|
||||||
(喂怎么概述就这么短这么懒啊?)
|
|
||||||
|
|
||||||
哎呀懒得废话那么多啦……
|
|
||||||
|
|
||||||
要想竞赛搞得好,网上刷题不可少;在线题库哪里找?通用测评大法好!
|
|
||||||
|
|
||||||
[UOJ](http://uoj.ac/)
|
|
@ -1,107 +0,0 @@
|
|||||||
# 安装
|
|
||||||
|
|
||||||
## 教练我想安装!
|
|
||||||
|
|
||||||
请参见 [README.md](https://github.com/vfleaking/uoj/blob/master/README.md) 来安装。
|
|
||||||
|
|
||||||
嘿嘿现在我假设你已经是超级管理员了!
|
|
||||||
|
|
||||||
那么你就可以新建题目了!
|
|
||||||
|
|
||||||
看看看,problem/1 这个文件夹,里面有一道样题,赶紧动手上传!(啊感觉我应该多给几道样题的)
|
|
||||||
|
|
||||||
关于如何传题请参见[题目文档](problem/)
|
|
||||||
|
|
||||||
啊如果你在 “与svn仓库同步” 的过程中发现 <samp>compile error</samp> 并且还说 <samp>no comment</samp> 的话……多半是……UOJ 尝试 ptrace 然而 ptrace 被禁了……
|
|
||||||
|
|
||||||
被禁了可能是被 docker 禁了,可以加一句 `--cap-add SYS_PTRACE` (见 [README.md](https://github.com/vfleaking/uoj/blob/master/README.md))……要是这样不能解决问题……是 Ubuntu/openSUSE 环境嘛?请尝试用下面的命令阻止 AppArmor 对 docker 的行为产生影响。当然把第二行加到 `rc.local` 里就不用每次重启都输入一遍啦~(详细解释戳 [→ 这里](https://github.com/docker/docker/issues/7276))
|
|
||||||
|
|
||||||
```sh
|
|
||||||
sudo apt-get install apparmor-utils
|
|
||||||
aa-complain /etc/apparmor.d/docker
|
|
||||||
```
|
|
||||||
|
|
||||||
要是这样还是不能解决问题……估计就是被黑恶势力禁掉了。。。大概就不是咱们这边的锅了,找找是哪个黑恶势力禁的吧。。。
|
|
||||||
|
|
||||||
另:如果上述方法不能解决 ptrace 问题也可以考虑使用 `--privileged`,但是这么做会导致 docker 失去其原有的隔离性而带来潜在的风险,不建议在生产环境中使用。
|
|
||||||
|
|
||||||
传题都没问题的话,感觉就可以愉快使用 UOJ 了!
|
|
||||||
|
|
||||||
## 教练我还想折腾!
|
|
||||||
|
|
||||||
嗯!来来来我们来折腾一波。
|
|
||||||
|
|
||||||
有个很厉害的配置文件,在 /var/www/uoj/app/.config.php 里,你可以配置一波……一个完全体如下:(有可能本文档没有跟上代码更新的速度,请以旁边的那个 .default-config.php 为准)
|
|
||||||
|
|
||||||
```php
|
|
||||||
<?php
|
|
||||||
return [
|
|
||||||
'database' => [ // 数据库相关
|
|
||||||
'database' => 'app_uoj233', // 数据库名称
|
|
||||||
'username' => 'root', // 用户名
|
|
||||||
'password' => '', // 密码
|
|
||||||
'host' => '127.0.0.1' // 数据库主机名
|
|
||||||
],
|
|
||||||
'web' => [ // 网址相关
|
|
||||||
'main' => [ // 网站主体
|
|
||||||
'protocol' => 'http', // 传输协议
|
|
||||||
'host' => 'local_uoj.ac', // 主机名
|
|
||||||
'port' => 80 // 端口
|
|
||||||
],
|
|
||||||
'blog' => [ // UOJ 博客 (用户名放前面之后成为完整的域名)
|
|
||||||
'protocol' => 'http', // 传输协议
|
|
||||||
'host' => 'blog.local_uoj.ac', // 主机名
|
|
||||||
'port' => 80 // 端口
|
|
||||||
]
|
|
||||||
],
|
|
||||||
'security' => [ // 安全相关(不要动)
|
|
||||||
'user' => [
|
|
||||||
'client_salt' => 'salt0'
|
|
||||||
],
|
|
||||||
'cookie' => [
|
|
||||||
'checksum_salt' => ['salt1', 'salt2', 'salt3']
|
|
||||||
],
|
|
||||||
],
|
|
||||||
'mail' => [ // 邮件相关(SMTP 协议发送)
|
|
||||||
'noreply' => [ // noreply 邮箱
|
|
||||||
'username' => 'noreply@none',
|
|
||||||
'password' => 'noreply',
|
|
||||||
'host' => 'smtp.sina.com',
|
|
||||||
'port' => 25
|
|
||||||
]
|
|
||||||
],
|
|
||||||
'judger' => [ // 测评相关(不要动)
|
|
||||||
'socket' => [ // 与测评机的 socket 服务器通讯的设置
|
|
||||||
'port' => '233', // 端口
|
|
||||||
'password' => 'password233' // 认证密码(证明自己 UOJ 服务器)
|
|
||||||
]
|
|
||||||
],
|
|
||||||
'svn' => [ // svn 相关(不要动)
|
|
||||||
'our-root' => [ // 每个题目的 svn 仓库自带的仓库管理员
|
|
||||||
'username' => 'our-root', // 管理员用户名
|
|
||||||
'password' => 'our-root' // 密码
|
|
||||||
]
|
|
||||||
],
|
|
||||||
'switch' => [ // 一些开关
|
|
||||||
'ICP-license' => false, // ICP 备案信息的显示
|
|
||||||
'web-analytics' => false, // 网站流量统计(记 uoj.ac 名下……想统计自己的得改代码)
|
|
||||||
'blog-use-subdomain' => true // 每个人的博客使用独立的子域名
|
|
||||||
]
|
|
||||||
];
|
|
||||||
```
|
|
||||||
|
|
||||||
### 域名
|
|
||||||
如果你想使用自己的域名,改 config 即可。
|
|
||||||
|
|
||||||
如果你是搭校内网站这种的,可能没有 DNS。你可以选择自己搭校内的 DNS 解析,或者自己改 hosts。
|
|
||||||
|
|
||||||
或者你想成为一条咸鱼,可以直接在 config 里的 host 那里写 ip。
|
|
||||||
|
|
||||||
Q:为什么博客用不了?
|
|
||||||
|
|
||||||
A:博客的话需要给每个用户的博客域名进行解析,最好是用泛解析解决,这是出于安全考虑。如果没这条件,可以将配置文件里`switch`中的`blog-use-subdomain`改成false,这样博客url将以子目录的形式出现。
|
|
||||||
|
|
||||||
### 邮箱
|
|
||||||
noreply 邮箱的目的是发一些莫名其妙的邮件,比如 svn 密码和 “找回密码”。
|
|
||||||
|
|
||||||
你可以随便找一个邮箱小号把账号密码塞这里,但是记得查查邮件服务商的 SMTP 服务器名和端口。以及,有些邮箱是需要手动开启某个开关才能允许 SMTP 发送邮件的。
|
|
@ -1,35 +0,0 @@
|
|||||||
# 维护
|
|
||||||
|
|
||||||
## 数据可持久化
|
|
||||||
|
|
||||||
(我并不是在说函数式线段树233)
|
|
||||||
|
|
||||||
有同学表示重启后 docker 丢失了数据。在这里要科普下 docker 的 image 和 container 的概念。
|
|
||||||
|
|
||||||
`run` 命令的功能是读一个 image 并运行,跑起来的 image 是一名光荣的 container,跑完的 container 还是一名光荣的 container。
|
|
||||||
|
|
||||||
所以当你关掉了你的 container 之后,使用 `run` 命令试图让它复活是不对的。。。
|
|
||||||
|
|
||||||
首先,你需要
|
|
||||||
```sh
|
|
||||||
docker ps -a
|
|
||||||
```
|
|
||||||
来查看所有正在运行或运行结束的 container,找到你刚才掐掉的那个(通常就是第一个),然后复制下它的 container id。然后:
|
|
||||||
```sh
|
|
||||||
docker restart <container-id>
|
|
||||||
```
|
|
||||||
这家伙就在后台默默跑起来了!如果你想让它回到前台,请用
|
|
||||||
```sh
|
|
||||||
docker attach <container-id>
|
|
||||||
```
|
|
||||||
当当!复活了!你以为丢失了的数据都回来了!(container 其实可以起名的,这种进阶用法自己探索吧233)
|
|
||||||
|
|
||||||
## 更新
|
|
||||||
|
|
||||||
当 github 上有更新的时候,如何更新自己本地的版本呢?
|
|
||||||
|
|
||||||
求看眼[开发](/dev/)最前面几行关于使用 svn 仓库的。
|
|
||||||
|
|
||||||
嗯好,假设你已经看完了。如果是 uoj 和 judge_client 的更新,那么你可以 svn checkout 一下,然后把 git 里的新版本 commit 上去……不过你以前 checkout 过的话就可以留着那个文件夹,下次就不用重新 checkout 了。
|
|
||||||
|
|
||||||
随着 UOJ 代码的更新,可能会有一些数据哇文件系统哇之类的更新,这种会被打包放在 app/upgrade 目录下。你只需要在 /var/www/uoj/app 下执行 `php cli.php upgrade:latest` 就好啦!
|
|
@ -1,263 +0,0 @@
|
|||||||
# 题目
|
|
||||||
## 上传题目
|
|
||||||
新建题目只有超级管理员有权限,所以想加题先要联系超级管理员君,点一下题库右下方的 “新建题目” 按钮。
|
|
||||||
|
|
||||||
新建题目后,超级管理员或该题目的题目管理员可以看到题目后台。后台分为三个选项卡:
|
|
||||||
|
|
||||||
1. 编辑:题面编辑页面
|
|
||||||
2. 管理者:题目管理员列表管理页面
|
|
||||||
3. 数据:题目数据管理页面
|
|
||||||
|
|
||||||
当然还有最后个 “返回” 选项卡退出后台。下面将逐一介绍这三个选项卡。
|
|
||||||
|
|
||||||
###编辑
|
|
||||||
该页面可以对题面本身进行编辑,还可以管理题目的标签。
|
|
||||||
|
|
||||||
####编辑题面
|
|
||||||
题面用 Markdown 编写。
|
|
||||||
|
|
||||||
理论上题面是可以自由编写的,但还是有一些推荐的格式。可参照 UOJ 上对应类型的题面(传统题,交互题,提交答案题等)
|
|
||||||
|
|
||||||
一些推荐的规则:
|
|
||||||
|
|
||||||
1. 中文与英文、数字之间加一个空格隔开。
|
|
||||||
2. 输入输出样例用 `<pre>` 标签包围,并且以一个空行结尾。(方便大家复制样例到终端后不用再打回车)
|
|
||||||
3. 题面中最高级标题为三级标题。这是因为题目名称是二级标题。
|
|
||||||
4. 名称超过一个字符的数学符号要用 mathrm。例如 `\mathrm{sgn}`, `\mathrm{lca}`。
|
|
||||||
4. 注意 `\max`, `\min`, `\gcd` 都是有现成的。
|
|
||||||
5. 注意 xor 这种名称超过一个字符的二元运算符请用 `\mathbin{\mathrm{xor}}`。
|
|
||||||
6. 一行内的计算机输入输出和常量字符串表达式请用 `<samp>` 标签,例如 `请输出 “<samp>NO SOLUTION</samp>”`, `<samp>aaa</samp> 中有三个 <samp>a</samp>`。
|
|
||||||
7. 一行内的计算机代码请用 <code>`</code> 括起来,就像上面的规则那样。
|
|
||||||
|
|
||||||
可参考下面这个例子:
|
|
||||||
```markdown
|
|
||||||
读入一个整数 $n$,表示题目中提到的 $3$ 位大爷 AC 的总题数。请输出他们分别 AC 的总题数。如果你不能正确读入,那么将获得 $0$ 分。前 $3$ 个测试点你正确读入即可获得 $6$ 分,第 4 个测试点你正确读入只能获得 $3$ 分。如果你不会做这道题,请直接输出 “<samp>WOBUHUI</samp>”
|
|
||||||
|
|
||||||
下面有一个样例:
|
|
||||||
<pre>
|
|
||||||
233
|
|
||||||
|
|
||||||
</pre>
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
####编辑标签
|
|
||||||
只需要用英文逗号隔开标签填入文本框就行。
|
|
||||||
|
|
||||||
推荐你使用如下几条规则填写标签:
|
|
||||||
|
|
||||||
1. 标签的目的是标出题目类型,方便用户检索题目。一般来说,标签顺序基本为从小范围到大范围。
|
|
||||||
2. 最前面的几个标签是这题所需要的前置技能,这里假定 “二分查找” 之类过于基础的技能选手已经掌握。
|
|
||||||
3. 接下来是这道题的大方法,比如 “贪心”、“DP”、“乱搞”、“构造”、“分治”……
|
|
||||||
4. 接下来,如果这道题是非传统题,用一个标签注明非传统题类型,比如 “提交答案”、“交互式”、“通讯”。
|
|
||||||
5. 接下来,如果这道题是模板题,用一个标签注明 “模板题”。
|
|
||||||
6. 接下来,如果这道题是不用脑子想就能做出的题,例如 NOIP 第一题难度,用一个标签注明 “水题”。
|
|
||||||
7. 最后,如果这题的来源比较重要,用一个标签注明。比如 “UOJ Round”、“NOI”、“WC”。
|
|
||||||
8. 前置技能中,“数学” 太过宽泛不能作为标签,但 “数论” 可以作为前置技能。
|
|
||||||
9. 如果有多个解法,每个解法的前值技能和大方法都不太一样,那么尽可能都标上去。
|
|
||||||
10. “乱搞” 标签不宜滥用。
|
|
||||||
|
|
||||||
|
|
||||||
###管理者
|
|
||||||
只有题目管理员和超级管理员才能看到后台,但只有题目管理员才能管理题目数据。
|
|
||||||
|
|
||||||
可以通过这个页面增加或删除题目管理员。
|
|
||||||
|
|
||||||
###数据
|
|
||||||
UOJ 使用 svn 管理题目数据,svn 仓库地址可以在本页面上找到。当你点了本页面的某个按钮后,UOJ 将把 svn 密码发送到你的邮箱。这个 svn 密码是不随题目变化而变化的。
|
|
||||||
|
|
||||||
但是,初始时 UOJ 是没有配置过用于给大家发邮件的邮箱的。所以如果你还没有配置过,请直接在数据库的 user\_info 表中找到 svn\_password 一栏存储的值;如果你愿意折腾一下,可以在 /var/www/uoj/app/.config.php 里配置一下邮箱,详情见[安装](/install/)咯~
|
|
||||||
|
|
||||||
1. 下载 svn,即 subversion。如果是 win 可以用 TortoiseSVN,如果是 ubuntu 直接 apt-get 一发,也可以用 smartsvn。
|
|
||||||
2. 学习怎么使用 svn。(蛮好懂的吧,会用 checkout,add,remove,commit 什么的就行了)
|
|
||||||
3. 在题目数据管理页面,获取 svn 密码。
|
|
||||||
4. checkout 这道题。
|
|
||||||
5. 在你的 working copy 下,建立文件夹 1,然后在 1 这个文件夹下放置题目数据什么的。
|
|
||||||
6. 搞完之后 commit。
|
|
||||||
7. 在网页上点“与SVN仓库同步”,就可以啦!
|
|
||||||
|
|
||||||
####题目配置格式
|
|
||||||
主要麻烦是要写个 problem.conf,下面主要介绍传统题的配置。
|
|
||||||
|
|
||||||
例如:
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
use_builtin_judger on
|
|
||||||
use_builtin_checker ncmp
|
|
||||||
n_tests 10
|
|
||||||
n_ex_tests 5
|
|
||||||
n_sample_tests 1
|
|
||||||
input_pre www
|
|
||||||
input_suf in
|
|
||||||
output_pre www
|
|
||||||
output_suf out
|
|
||||||
time_limit 1
|
|
||||||
memory_limit 256
|
|
||||||
output_limit 64
|
|
||||||
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
假如你 input 文件是 www1.in, www2.in, ... 这个样子,那么你需要在 problem.conf 里记录:
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
input_pre www
|
|
||||||
input_suf in
|
|
||||||
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
output 文件同理。
|
|
||||||
|
|
||||||
extra test 是指额外数据,在 AC 的情况下会测额外数据,如果某个额外数据通不过会被倒扣3分。
|
|
||||||
|
|
||||||
至于样例,样例一定是前几个额外数据,所以有一个 `n_sample_tests` 表示是前多少组是样例。你需要把题面中的样例和大样例放进额外数据里。
|
|
||||||
|
|
||||||
额外数据命名形如 ex\_www1.in, ex\_www2.in, ... 这个样子。
|
|
||||||
|
|
||||||
checker 是指判断选手输出是否正确的。一般来说输出结果为整数序列,用 ncmp 就够了,它会比较标准答案的整数序列和选手输出的整数序列。如果是忽略所有空白字符,进行字符串序列的比较,可以用wcmp。如果你想按行比较(不忽略行末空格,但忽略文末回车),可以使用 fcmp。如果想手写 checker,请使用 Codeforces 的 [testlib](http://codeforces.com/testlib) 库写 checker。
|
|
||||||
|
|
||||||
你需要写好后命名为 chk.cpp,然后在 problem.conf 中去掉 “use\_builtin\_checker” 一行。
|
|
||||||
|
|
||||||
如果你的题目的输入数据可以被检验是否满足题目要求,那么请写一个 validator。比如“保证数据随机”“保证数据均为人手工输入”等就无法检验输入数据是否满足题目要求。
|
|
||||||
|
|
||||||
validator 的作用就是检查你输入数据造得是否合法。比如你输入保证是个连通图,validator 就得检验这个图是不是连通的。还是请用 testlib 写,教程还是之前提到的那个教程。写好后命名为 val.cpp 就行。
|
|
||||||
|
|
||||||
另外注意时间限制**不能为小数**。
|
|
||||||
|
|
||||||
#### 提交答案题的配置
|
|
||||||
范例:
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
use_builtin_judger on
|
|
||||||
submit_answer on
|
|
||||||
n_tests 10
|
|
||||||
input_pre www
|
|
||||||
input_suf in
|
|
||||||
output_pre www
|
|
||||||
output_suf out
|
|
||||||
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
So easy!
|
|
||||||
|
|
||||||
不过还没完……你要写个 checker。当然如果你是道 [最小割计数](http://uoj.ac/problem/85) 就不用写了。。。老样子写个 use\_builtin\_checker ncmp 就行。
|
|
||||||
|
|
||||||
提答题经常会面临给部分分,请使用 quitp 函数。由于一些历史原因(求不吐槽 QAQ),假设测试点满分为 a,则
|
|
||||||
```cpp
|
|
||||||
quitp(x, "haha");
|
|
||||||
```
|
|
||||||
将会给 floor(a * round(100x) / 100) 分。是不是很复杂……其实很简单,当你这个测试点想给 p 分的时候,只要
|
|
||||||
```cpp
|
|
||||||
quitp(ceil(100.0 * p / a) / 100, "haha");
|
|
||||||
```
|
|
||||||
就行了。(好麻烦啊)
|
|
||||||
|
|
||||||
假设你已经写好了,赞!
|
|
||||||
|
|
||||||
但是下发的本地 checker 怎么办?
|
|
||||||
|
|
||||||
首先你得会写本地 checker。如果只是传参进来一个测试点编号,检查测试点是否正确,那么只要善用 registerTestlib 就行了。如果你想让 checker 与用户交互,请使用 registerInteraction。特别地,如果你想让 checker 通过终端与用户进行交互,请使用如下代码(好丑啊)
|
|
||||||
```cpp
|
|
||||||
char *targv[] = {argv[0], "inf_file.out", (char*)"stdout"};
|
|
||||||
#ifdef __EMSCRIPTEN__
|
|
||||||
setvbuf(stdin, NULL, _IONBF, 0);
|
|
||||||
#endif
|
|
||||||
registerInteraction(3, targv);
|
|
||||||
```
|
|
||||||
|
|
||||||
那么怎么下发文件呢?你可以在文件夹 1/ 下新建一个文件夹 download,里面放的所有东西都会打包发给选手啦~
|
|
||||||
|
|
||||||
#### 交叉编译
|
|
||||||
|
|
||||||
由于你的本地 checker 可能需要发布到各个平台,所以你也许需要交叉编译。交叉编译的意思是在一个平台上编译出其他平台上的可执行文件。好!下面是 Ubuntu 上交叉编译小教程时间。
|
|
||||||
|
|
||||||
首先不管三七二十一装一些库:(请注意 libc 和 libc++ 可能有更新的版本)
|
|
||||||
```sh
|
|
||||||
sudo apt-get install libc6-dev-i386
|
|
||||||
sudo apt-get install lib32stdc++6 lib32stdc++-4.8-dev
|
|
||||||
sudo apt-get install mingw32
|
|
||||||
```
|
|
||||||
|
|
||||||
然后就能编译啦:
|
|
||||||
```sh
|
|
||||||
g++ localchk.cpp -o checker_linux64 -O2
|
|
||||||
g++ localchk.cpp -m32 -o checker_linux32 -O2
|
|
||||||
i586-mingw32msvc-g++ localchk.cpp -o checker_win32.exe -O2
|
|
||||||
```
|
|
||||||
|
|
||||||
问:那其他系统怎么办?有个叫 emscripten 的东西,可以把 C++ 代码编译成 javascript。请务必使用 UOJ 上的 testlib,而不是 CF 上的那个版本。由于 testlib 有些黑科技,UOJ 上的 testlib 对 emscripten 才是兼容的。
|
|
||||||
|
|
||||||
[emscripten 下载地址](http://kripken.github.io/emscripten-site/docs/getting_started/downloads.html) (建议翻墙提升下载速度)
|
|
||||||
|
|
||||||
编译就用
|
|
||||||
```sh
|
|
||||||
em++ localchk.cpp -o checker.js -O2
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 交互题的配置
|
|
||||||
嘛……其实并没有 UOJ 内部并没有显式地支持交互式(真正的程序与程序交互的版本还没发布出来),只是提供了 require、implementer 和 token 这两个东西。
|
|
||||||
|
|
||||||
除了前文所述的 download 这个文件夹,还有一个叫 require 的神奇文件夹。在测评时,这个文件夹里的所有文件均会被移动到与选手源程序同一目录下。在这个文件夹下,你可以放置交互库,供编译时使用。
|
|
||||||
|
|
||||||
再来说 implementer 的用途。如果你在 problem.conf 里设置 `with_implementer on` 的话,各个语言的编译命令将变为:
|
|
||||||
|
|
||||||
* C++: g++ code implementer.cpp code.cpp -lm -O2 -DONLINE_JUDGE
|
|
||||||
* C: gcc code implementer.c code.c -lm -O2 -DONLINE_JUDGE
|
|
||||||
* Pascal: fpc implementer.pas -o code -O2
|
|
||||||
|
|
||||||
好……不管那些奇怪的选手的话,一个交互题就搞好了……你需要写 implementer.cpp、implementer.c 和 implementer.pas。当然你不想兹瓷某个语言的话不写对应的交互库就好了。
|
|
||||||
|
|
||||||
如果是 C/C++,正确姿势是搞一个统一的头文件放置接口,让 implementer 和选手程序都 include 这个头文件。把主函数写在 implementer 里,连起来编译时程序就是从 implementer 开始执行的了。
|
|
||||||
|
|
||||||
如果是 Pascal,正确姿势是让选手写一个 pascal unit 上来,在 implementer.pas 里 uses 一下。除此之外也要搞另外一个 pascal unit,里面存交互库的各种接口,让 implementer 和选手程序都 uses 一下。
|
|
||||||
|
|
||||||
哦另外 require 文件夹的内容显然不会被下发……如果你想下发一个样例交互库,可以放到 download 文件夹里。
|
|
||||||
|
|
||||||
好下面来解释什么是 token……考虑一道典型的交互题,交互库跟选手函数交流得很愉快,最后给了个满分。此时交互库输出了 “AC!!!” 的字样,也可能输出了选手一共调用了几次接口。但是聪明的选手发现,只要自己手动输出一下 “AC!!!” 然后果断退出似乎就能骗过测评系统了娃哈哈。
|
|
||||||
|
|
||||||
这是因为选手函数和交互库已经融为一体成为了一个统一的程序,测评系统分辨出谁是谁。这时候,token 就出来拯救世界了。
|
|
||||||
|
|
||||||
在 problem.conf 里配置一个奇妙的 token,比如 `token wahaha233`,然后把这个 token 写进交互库的代码里(线上交互库,不是样例交互库)。在交互库准备输出任何东西之前,先输出一下这个 token。当测评系统要给选手判分时,首先判断文件的第一行是不是 token,如果不是,直接零分。这样就避免了奇怪的选手 hack 测评系统了。这里的 token 判定是在调用 checker 之前,测评系统会把 token 去掉之后的选手输出喂给 checker。(所以一道交互题的 token 要好好保护好)
|
|
||||||
|
|
||||||
另外另外,记得在 C/C++ 的交互库里给全局变量开 static,意为仅本文件可访问。
|
|
||||||
|
|
||||||
#### 意想不到的非传统题
|
|
||||||
吼,假如你有一道题不属于上述任何一种题目类型 —— 恭喜你中奖啦!得自己写 judger 啦!
|
|
||||||
|
|
||||||
judger 的任务:给你选手提交的文件,把测评结果告诉我。
|
|
||||||
|
|
||||||
把 problem.conf 里的 `use_builtin_judger on` 这行去掉,搞一个 judger 放在题目目录下,就好了。
|
|
||||||
|
|
||||||
噢对怎么搞这个 judger 呢。。。全自动啦233。。。你需要写个 Makefile……比如
|
|
||||||
```makefile
|
|
||||||
export INCLUDE_PATH
|
|
||||||
CXXFLAGS = -I$(INCLUDE_PATH) -O2
|
|
||||||
|
|
||||||
all: chk judger
|
|
||||||
|
|
||||||
% : %.cpp
|
|
||||||
$(CXX) $(CXXFLAGS) $< -o $@
|
|
||||||
```
|
|
||||||
|
|
||||||
什么?你问 judger 应该怎么写?
|
|
||||||
|
|
||||||
很抱歉的是这部分我封装得并不是很方便……请 include 一下 uoj_judger.h 来辅助你写 judger……参照 QUINE 这个样题……
|
|
||||||
|
|
||||||
说实在的 uoj_judger.h 写得太丑了(不过反正我会用2333)。期待神犇再来造一遍轮子,或者用 python 码个框架(需要解决 python 启动就耗时 40ms 的坑爹问题)
|
|
||||||
|
|
||||||
哦对,要使用自己的 judger 的话就只有超级管理员能 “与 SVN 仓库同步” 了。另外无论你的 judger 如何折腾,测评也是有 10 分钟 的时间限制的。
|
|
||||||
|
|
||||||
## 样题
|
|
||||||
在 problem 文件夹下有我们给出的几道样题。
|
|
||||||
|
|
||||||
1. 一个典型的传统题
|
|
||||||
* \#1. A + B Problem。
|
|
||||||
2. 一个典型的非传统题:
|
|
||||||
* \#8. Quine。
|
|
||||||
3. 一个典型的交互题:
|
|
||||||
* \#52. 【UR \#4】元旦激光炮。
|
|
||||||
4. 一个典型的 ACM 赛制题(错一个就 0 分):
|
|
||||||
* \#79. 一般图最大匹配。
|
|
||||||
5. 一个典型的提交答案题:
|
|
||||||
* \#116. 【ZJOI2015】黑客技术。
|
|
||||||
6. 一个典型的 subtask 制的题:
|
|
||||||
* \#225. 【UR #15】奥林匹克五子棋。
|
|
@ -1,11 +0,0 @@
|
|||||||
site_name: UOJ Documentation
|
|
||||||
pages:
|
|
||||||
- 主页: 'index.md'
|
|
||||||
- 安装: 'install.md'
|
|
||||||
- 维护: 'maintain.md'
|
|
||||||
- 题目: 'problem.md'
|
|
||||||
- 比赛: 'contest.md'
|
|
||||||
- 开发: 'dev.md'
|
|
||||||
- 关于: 'about.md'
|
|
||||||
theme: cerulean
|
|
||||||
extra_css: [extra.css]
|
|
BIN
problem/1.zip
BIN
problem/1.zip
Binary file not shown.
BIN
problem/116.zip
BIN
problem/116.zip
Binary file not shown.
BIN
problem/225.zip
BIN
problem/225.zip
Binary file not shown.
BIN
problem/52.zip
BIN
problem/52.zip
Binary file not shown.
BIN
problem/79.zip
BIN
problem/79.zip
Binary file not shown.
BIN
problem/8.zip
BIN
problem/8.zip
Binary file not shown.
Loading…
Reference in New Issue
Block a user