文件的存放和定义
文件路径
当然事实上,如果你使用 tuack.gen 生成一个工程,本部分大多数事情都不用太关心。否则请参看这里讲到的文件存放路径规定。
所有数据文件,会默认用用大文件系统 git lfs 管理,使用方式见相关工具-git 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 conf.json/yaml //每层文件夹都有一个配置文件,这是一个“比赛”工程
//不再需要title.tex文件,比赛的名字等基本信息定义在conf.*中
//不再需要把本工具放在工程目录中了
day1 //和conf.json的subdir匹配的路径,表示这个比赛工程的子“比赛日”
day2 //匹配的另一个“比赛日”工程
conf.json/yaml //这是一个“比赛日”的工程,一个比赛日可以单独存放
interval //和比赛日conf.*的subdir匹配的路径,表示这个比赛工程的“题目”
drink
nodes //这个比赛日有3个题目
conf.json/yaml //这是一个“题目”的工程,一个题目也可以单独存放
statement //题面,详见gen生成出来的例子
zh-cn.md //一般使用这一个
en.md //如果是英文题面用这个
assignment[.pdf] //命题报告,一个文件或文件夹,单文件用pdf、pptx、html等可以直接看的格式,
// 如果是文件夹必须用.dir结尾,不能没有后缀名,下同
discussion[.pdf] //讲题/题目讨论PPT,一个文件或文件夹
solution[.docx] //题解,一个文件夹或文件
data //一定包含一个评测用数据的文件夹
1.in //文件推荐用<编号>.<后缀名>的格式命名,也可以用别的方式
1.ans //标准输出文件是.ans
...
10.ans
chk //checker统一使用chk命名,需要编译的话提供一个同名文件夹。
//!TODO:这里未来会增加对不同评测环境的支持,用make <环境名称>生成对应环境chk。
chk.cpp //如果用正常的g++命令编译,就这么放
testlib.h //可以有其他文件
down //一定包含一个下发文件夹
1.in //第一个样例;对于提交答案题,这【不是】第一个下发数据
1.ans //这里的编号和题面中的样例编号相同,题面中出现的样例也要在这里给出
2.in
...
decimal.cpp //这道题没有这个啦,这个是要下发的代码,其他任何要下发的文件同理
checker //对于需要编译后下发的,仍然是提供一个文件夹
checker.cpp //和上面一样,正常编译就这样,否则提供makefile
testlib.h
sample_programs.dir //极少的题目需要下发一个目录,规定这样的目录+.dir好了,下发时会删除.dir
sample.cpp //这些完全可以不放在目录中下发
sample.pas
pre //一定包含一个pre-test文件夹,可以为空
1.in //格式同上
1.ans
gen //如果出题人写了数据生成器,放在这里,不规定格式
vfk //每个出题人/验题人建立一个目录
picks //这是另一个验题人
val //如果你写了数据检查器请放在这样命名的文件夹下,具体格式见后文
data.test //如果你不是出题人但是出了数据
chk.test //如果你写了checker的测试,装在这个文件夹下
checker.test //同理,不要问我同名怎么办
n_log_n //推荐每个模拟选手的测试用一个文件夹装,但现在不放在不放在子目录下也行了
nodes.cpp或1.out //这就是一个模拟选手,用标准IO
Dinic //另一个模拟选手,名称随意,不要匹配到像其他东西的名称就行
1.out
...
SPFA.cpp //现在也可以这么放置源代码了
hehe.dir //如果你有其他文件夹,觉得想分享给大家,又不是模拟选手,用.dir
rename.py //可以有其他想要分享的文件
resources //题面中使用的外部资源,例如图片、html或tex的模板
1.jpg //和题面中名称相同的图片
tables //需要用到的表格
data[.json] //和题面中名称相同的表格,用python或json+jinja模板做(可以纯json)
precautions //此次比赛的选手注意事项,会根据模板渲染到相应的位置
zh-cn.md
lectures //有讲座的活动(WC、APIO等),讲座的东西(包括集训队交流)
picks //装在一个自己名字命名的文件夹里面
vfk //名字应该不会重复吧2333
题目描述文件
conf.json/yaml 是一个工程或其子工程的描述文件,你总是可以手工编辑这个文件来实现所想要的功能。
conf.json/yaml 必须是一个 json 或 yaml 文件,恰好包含一个dict/object,并且有一个元素为 "folder" : "类型"。类型 必须为 contest,day,problem,extend 中的一种。如果不含有 folder 元素,则认为是 problem。
注意 json 文件不能包含注释 ,部分 yaml 解析工具也没法解析注释,下面的注释是为了说明用法和规定,使用时请删除;程序运行前会验证 json/yaml 文件的合法性。
注意到有的人只熟悉 json 不熟悉 yaml,在使用任何会改变 conf.* 文件的操作时,加上 -d json 可以将相应文件保存成 json格式。当 yaml 和 json 同时存在时,脚本会优先读 yaml 的文件。
下面是 conf.json/yaml 的格式要求。
folder : contest #yaml的dict既可以写成多行的冒号形式,也可以写成一行的大括号
name : NOI2016TEST #这个是比赛的名字,用于输出的文件夹名字等
title : #标题用于渲染题面,标题和名字是不同的东西
zh-cn : NOI2016模拟赛 #不同语言不会出现在同一份题面中
short title : { zh-cn : NOI-2016-TEST } #这个是标题的简写,一般是官方给的
subtitle : { zh-cn : by zgg } #与前面简写区分开的,这是子标题,例如“冬令营”
subdir : [ day0 , day1 , day2 ] #包含的比赛场次的文件夹名称,这是数组的一行写法
folder : day
name : day1
subdir : [ excellent , grid , cyclic ] #包含的题目的文件夹路径,可以用包含左斜杠的路径
title : #用来渲染题面,如果不造题面可以不写
zh-cn : 第一试 #用dict来描述国际化,可以单用一个字符串
en : Day 1 #只写语言不写地区表示所有使用该语言的地区
start time : 2016-07-24 08:00:00+0800 #目前只用于渲染题面,不排除可以用于比赛,需要严格按格式写
end time : 2016-07-24 13:00:00+0800
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 folder : problem
type : program #program传统,output提交答案,interactive交互
name : excellent #建议加上题目名称,没有的话默认是文件夹名字
title : { zh-cn : 优秀的拆分 } #现在标题要区分语言,原来的中文名称cnname停用
time limit : 1.5 #时间限制,uoj会自动向上取整(如果不同环境限制不同,用继承)
memory limit : 512 MB #空间限制,必须加上单位
output limit : 100 KB #单个文件的输出长度限制
partial score : false #是否有部分分,默认没有,只用于显示在题面上
compile : { c : -O2 -std=c14 , cpp : -O2 -std=c++14 , java : '' , pas : -O2 , py : '' } #各个语言的编译开关
input_table : { zh-cn : input.txt } #强行更改题面中的输入文件名称
output_table : { zh-cn : output.txt } #强行更改题面中的输出文件名称
args : [ 10 , 30000 ] #这是全局参数,由出题人自定义,也可以在题面中引用,可以不是数组[]而是字典{}或其他什么东西;TODO:未来会传给val
data : #这是每个测试点的参数,注意只有args是出题人自己定义的
- cases : [ 1 , 2 ] #这是测试点1和2的公共参数;如果打包评测则是一个包
score : 11 #如果打包评测是这个包的分数,否则没用;没有这项参数的包将假设满分是100分然后平分剩下的分数(可能为负数)
args : [ 300 , 1 ] #这些测试点的参数,由出题人自定义,会传给val,也可以在题面中引用
time limit : 1.0 #可选,有的话将覆盖全局变量,全有可不设全局变量,下同(tester还没写)
memory limit : 64 MB
- args : [ 200 , 1 ] #每一项前面加减号是数组的另一种写法
cases : [ 3 , 4 ]
score : 19
... #中间可以有很多组这样的数据,注意这个省略号不能实际出现
- args : [ 30000 , 0 ]
cases : [ 20 ]
score : 5
samples : [ ... ] #样例,格式同data,省略号同样不能实际出现
pre : [ ... ] #预测试数据,格式同data
users : #验题人
picks : #一个验题人写了多个算法
Dinic : #算法的名称
expected : '<= 40' #期望得分,等效于写python的表达式右半块
path : picks/Dinic/hehe.cpp #路径,非传统题必须是文件夹路径,传统题是文件名
n_log_n :
expected : [ '>= 80' , '< 100' ] #期望得分可以有多个条件,取and
path : picks/n_log_n/excellent.cpp
vfk :
std :
expected : 'in range(100, 101)' #期望得分还可以有更复杂的python语法
path : vfk/std.cpp
uoj id : 3 #如果要使用上传到uoj的功能,需要填写这道题目的uoj题目id
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 folder : extend #继承类型,可以继承上面三种和继承本身
base path : cyclic #继承的原始路径
time limit : 3 #同名字段表示覆盖,例如换了评测环境以后时限变长了
title+ : #字段后加"+"表示合并,dict合并时子字段会递归
en : This problem has a new English name now
zh-cn : 我要换个中文名字 #原来有的字段在子结构中递归覆盖
data+ : #现在想要增加一些数据,数组是直接加到后面合并
- cases : #注意前面有个减号,这是数组的一项,这一项是一个dict
- ex1 #出了两组加强数据
- ex2
- ':1' #访问被继承的路径,前面加冒号
users : #不加加号是覆盖,表示重新指定相关程序
cy :
ps :
expected : {}
path : :cy/base/exam.cpp #访问被继承的路径也使用冒号
std :
expected : {}
path : :cy/std/exam.cpp
关于 args 和 data 中 args 的说明:这两个参数全部是出题人自己定义的,这意味着 args 下的数据结构可以由你自己定义。原理上你可以根本不定义这些参数,但为了达到前面的参数不重复原则,我们建议你配置这些参数。
我们推荐将所有数据的参数全部放在这里,题面的书写工具提供了获取这些参数的方法,你的数据生成器一般也有方法读取这个json文件(虽然C++也有相关的轮子,但如果不会的话你可以用python读了传给C++),未来我们还会将这些参数传给val。