├── .gitignore ├── LICENSE ├── README.md ├── fuzzy-cnoi-statement.typ ├── template ├── color1.in ├── fig.png └── main.typ ├── thumbnail.png └── typst.toml /.gitignore: -------------------------------------------------------------------------------- 1 | *.pdf -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT No Attribution 2 | Copyright © 2024 Wallbreaker5th 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so. 5 | 6 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Fuzzy CNOI Statement 2 | 3 | Fuzzy CNOI Statement is a template for CNOI(Olympiad in Informatics in China)-style statements for competitive programming. 4 | 5 | Fuzzy CNOI Statement 是一个 CNOI 题面排版风格的 Typst 模板。 6 | 7 | It is mainly designed to mimic the appearance of official CNOI-style statements, which are usually generated by [TUACK](https://gitee.com/mulab/oi_tools). 8 | 9 | 其主要模仿国内 NOI 系列比赛官方题面的外观。这些题面一般由 [TUACK](https://gitee.com/mulab/oi_tools) 生成。 10 | 11 | This template is not affiliated with the China Computer Federation (CCF) or the NOI Committee. When using this template, it is recommended to indicate the unofficial nature of the contest to avoid misunderstandings. 12 | 13 | 该模板与中国计算机学会(CCF)、NOI 委员会官方无关。在使用该模板时,建议标明比赛的非官方性质,以免造成误解。 14 | 15 | ## Usage 16 | Here are the fonts that this template will use, you can change the font by passing parameters:\ 17 | 以下是该模板会用到的字体,你可以通过传入参数的方式更换字体: 18 | - Consolas 19 | - New Computer Modern 20 | - 方正书宋(FZShuSong-Z01S) 21 | - 方正黑体(FZHei-B01S) 22 | - 方正仿宋(FZFangSong-Z02S) 23 | - 方正楷体(FZKai-Z03S) 24 | 25 | ```typ 26 | // Define your contest information and problem list 27 | // 定义比赛信息和题目列表 28 | 29 | #let (init, title, problem-table, next-problem, filename, current-filename, current-sample-filename, data-constraints-table-args) = document-class( 30 | contest-info, 31 | prob-list, 32 | ) 33 | 34 | #show: init 35 | 36 | #title() 37 | 38 | #problem-table() 39 | 40 | *注意事项(请仔细阅读)* 41 | + ... 42 | 43 | #next-problem() 44 | == 题目描述 45 | ... 46 | ``` 47 | 48 | Refer to `main.typ` for a complete example. 49 | 50 | `main.typ` 提供了一个完整的示例。 51 | -------------------------------------------------------------------------------- /fuzzy-cnoi-statement.typ: -------------------------------------------------------------------------------- 1 | // Typst template for making NOI-like problems 2 | // Author: Wallbreaker5th 3 | // MIT-0 License 4 | 5 | #import "@preview/codelst:2.0.0": sourcecode 6 | 7 | #let 字号 = ( 8 | 初号: 42pt, 9 | 小初: 36pt, 10 | 一号: 26pt, 11 | 小一: 24pt, 12 | 二号: 22pt, 13 | 小二: 18pt, 14 | 三号: 16pt, 15 | 小三: 15pt, 16 | 四号: 14pt, 17 | 中四: 13pt, 18 | 小四: 12pt, 19 | 五号: 10.5pt, 20 | 小五: 9pt, 21 | 六号: 7.5pt, 22 | 小六: 6.5pt, 23 | 七号: 5.5pt, 24 | 小七: 5pt, 25 | ) 26 | 27 | #let default-fonts = ( 28 | mono: "Consolas", 29 | serif: "New Computer Modern", 30 | cjk-serif: "FZShuSong-Z01S", 31 | cjk-sans: "FZHei-B01S", 32 | cjk-mono: "FZFangSong-Z02S", 33 | cjk-italic: "FZKai-Z03S", 34 | ) 35 | 36 | 37 | #let empty-par = { 38 | par()[ 39 | #v(0em, weak: true) 40 | #h(0em) 41 | ] 42 | } 43 | #let add-empty-par(it) = { 44 | it 45 | empty-par 46 | } 47 | 48 | 49 | #let default-problem-fullname(problem) = { 50 | if (problem.at("name", default: none) != none) { 51 | problem.name 52 | if (problem.at("name-en", default: none) != none) { 53 | "(" + problem.name-en + ")" 54 | } 55 | } else { 56 | problem.at("name-en", default: "") 57 | } 58 | } 59 | 60 | #let default-header(contest-info, current-problem) = { 61 | set par(first-line-indent: 0em) 62 | if (current-problem == none) { 63 | return 64 | } 65 | set text(size: 字号.五号) 66 | contest-info.name 67 | h(1fr) 68 | let round = contest-info.at("round", default: none) 69 | if (round != none) { 70 | round + " " 71 | } 72 | default-problem-fullname(current-problem) 73 | v(-2pt) 74 | line(length: 100%, stroke: 0.3pt) 75 | } 76 | 77 | #let default-footer(contest-info, current-problem) = { 78 | if (current-problem == none) { 79 | return 80 | } 81 | set text(size: 字号.五号) 82 | align(center,{ 83 | [第] 84 | counter(page).display() 85 | [页] 86 | h(2em) 87 | [共] 88 | context{ 89 | let cnt = counter(page).final().at(0) 90 | link((page:cnt, x:0pt, y:0pt), text(fill: rgb("#00f"), [#cnt])) 91 | } 92 | [页] 93 | }) 94 | } 95 | 96 | #let make-formula(s) = { 97 | let numbers = s.matches(regex("[\d.]+")) 98 | let last-end = 0 99 | for n in numbers { 100 | let start = n.start 101 | let end = n.end 102 | let number = n.text 103 | s.slice(last-end, start) 104 | math.equation(number) 105 | last-end = end 106 | } 107 | s.slice(last-end, s.len()) 108 | } 109 | 110 | 111 | #let current-problem-idx = counter("current-problem-idx") 112 | #let statement-page-begin = state("statement-page-begin", false) 113 | 114 | #let document-class( 115 | contest-info, 116 | problem-list, 117 | custom-fonts: (:), 118 | header: default-header, 119 | footer: default-footer, 120 | ) = { 121 | let fonts = default-fonts + custom-fonts 122 | 123 | let get-current-problem(here) = { 124 | let idx = current-problem-idx.at(here).at(0) - 1 125 | if (idx >= 0) { problem-list.at(idx) } 126 | } 127 | 128 | let init(it) = { 129 | set text(font: (( 130 | name: fonts.serif, 131 | covers: "latin-in-cjk" 132 | ), fonts.cjk-serif), size: 字号.小四, lang: "zh", region: "CN") 133 | show emph: set text(font: (( 134 | name: fonts.serif, 135 | covers: "latin-in-cjk" 136 | ), fonts.cjk-italic)) 137 | show strong: st => { // Dotted strong text 138 | set text(font: (( 139 | name: fonts.serif, 140 | covers: "latin-in-cjk" 141 | ), fonts.cjk-sans)) 142 | show regex("\p{sc=Hani}+"): s => { 143 | underline(s, offset: 3pt, stroke: ( 144 | cap: "round", 145 | thickness: 0.1em, 146 | dash: (array: (0em, 1em), phase: 0.5em) 147 | )) 148 | } 149 | st 150 | } 151 | show raw: set text(font: (( 152 | name: fonts.mono, 153 | covers: "latin-in-cjk" 154 | ), fonts.cjk-mono), size: 字号.小四) 155 | 156 | set list(indent: 1.75em, marker: ([•], [#h(-1em)•])) 157 | set enum( 158 | indent: 1.75em, 159 | numbering: x => { 160 | grid( 161 | columns: (0em, auto), 162 | align: bottom, 163 | hide[悲], numbering("1.", x) 164 | ) // As a workaround 165 | } 166 | ) 167 | 168 | show heading: set text(font: (( 169 | name: fonts.serif, 170 | covers: "latin-in-cjk"), 171 | fonts.cjk-sans), weight: 500) 172 | show heading.where(level: 1): it => { 173 | set text(size: 字号.小二) 174 | set heading(bookmarked: true) 175 | pad(top: 8pt, align(center, it)) 176 | } 177 | show heading.where(level: 2): it => { 178 | set text(size: 字号.小四) 179 | set heading(bookmarked: true) 180 | pad(left: 1.5em, top: 1em, bottom: .5em, [【]+box(it)+[】]) 181 | } 182 | 183 | show raw.where(block: true): it => { 184 | show raw.line: it => { 185 | if (it.text == "" and it.number == it.count) { 186 | return 187 | } 188 | box( 189 | grid( 190 | columns: (0em, 1fr), 191 | align: (right, left), 192 | move( 193 | text(str(it.number), fill: gray, size: 0.8em), 194 | dx: -1em, 195 | dy: 0.1em, 196 | ), 197 | it.body 198 | ) 199 | ) 200 | } 201 | pad( 202 | rect(it, stroke: 0.5pt + rgb("#00f"), width: 100%, inset: (y: 0.7em)), 203 | left: 0.5em 204 | ) 205 | } 206 | 207 | // Page Layout 208 | set page( 209 | margin: 2.4cm, 210 | header: context header(contest-info, get-current-problem(here())), 211 | footer: context if(statement-page-begin.at(here())) { 212 | footer(contest-info, get-current-problem(here())) 213 | }, 214 | ) 215 | 216 | show table: pad.with(y: .5em) 217 | 218 | set par(first-line-indent: (amount: 2em, all: true), leading: 0.7em) 219 | // Looks right but I'm not sure about the exact value 220 | set par(spacing: 0.6em) 221 | 222 | it 223 | } 224 | 225 | 226 | let title() = { 227 | align(center, { 228 | text(contest-info.name, size: 字号.二号, font: (( 229 | name: fonts.serif, 230 | covers: "latin-in-cjk" 231 | ), fonts.cjk-sans)) 232 | 233 | parbreak() 234 | v(10pt) 235 | 236 | let name-en = contest-info.at("name-en", default: none) 237 | if (name-en != none) { 238 | text(name-en, size: 字号.小一) 239 | parbreak() 240 | v(10pt) 241 | } 242 | 243 | 244 | let round = contest-info.at("round", default: none) 245 | if (round != none) { 246 | emph(text(round, size: 字号.二号)) 247 | parbreak() 248 | } 249 | 250 | let author = contest-info.at("author", default: none) 251 | if (author != none) { 252 | text(author, size: 字号.小三, font: (( 253 | name: fonts.serif, 254 | covers: "latin-in-cjk" 255 | ), fonts.cjk-sans)) 256 | parbreak() 257 | v(5pt) 258 | } 259 | 260 | let time = contest-info.at("time", default: none) 261 | if (time != none) { 262 | text(time, size: 字号.小三, font: (( 263 | name: fonts.serif, 264 | covers: "latin-in-cjk" 265 | ), fonts.cjk-sans)) 266 | } 267 | }) 268 | } 269 | 270 | let problem-table( 271 | extra-rows: (:), 272 | languages: (("C++", "cpp"),), 273 | compile-options: (("C++", "-O2 -std=c++14 -static"),), 274 | ) = { 275 | let default-row = ( 276 | wrap: text, 277 | always-display: false, 278 | default: "无", 279 | ) 280 | let rows = ( 281 | name: ( 282 | name: "题目名称", 283 | always-display: true, 284 | ), 285 | type: ( 286 | name: "题目类型", 287 | always-display: true, 288 | default: "传统型", 289 | ), 290 | name-en: ( 291 | name: "目录", 292 | wrap: raw, 293 | always-display: true, 294 | ), 295 | executable: ( 296 | name: "可执行文件名", 297 | wrap: raw, 298 | always-display: true, 299 | default: x => x.name-en, 300 | ), 301 | input: ( 302 | name: "输入文件名", 303 | wrap: raw, 304 | always-display: true, 305 | default: x => x.name-en + ".in", 306 | ), 307 | output: ( 308 | name: "输出文件名", 309 | wrap: raw, 310 | always-display: true, 311 | default: x => x.name-en + ".out", 312 | ), 313 | time-limit: ( 314 | name: "每个测试点时限", 315 | wrap: make-formula, 316 | ), 317 | memory-limit: ( 318 | name: "内存限制", 319 | wrap: make-formula, 320 | ), 321 | test-case-count: ( 322 | name: "测试点数目", 323 | default: "10", 324 | wrap: make-formula, 325 | ), 326 | subtask-count: ( 327 | name: "子任务数目", 328 | default: "1", 329 | ), 330 | test-case-equal: ( 331 | name: "测试点是否等分", 332 | default: "是", 333 | ), 334 | ) + extra-rows 335 | rows = rows.pairs().map( 336 | row => (row.at(0), default-row + row.at(1)) 337 | ) 338 | 339 | set table(align: bottom) 340 | let first-column-width = if (problem-list.len() <= 3) { 22% } else { 1fr } 341 | let columns = (first-column-width, ) + (1fr, ) * problem-list.len() 342 | table( 343 | columns: columns, 344 | stroke: 0.4pt, 345 | ..{ 346 | rows.filter(row => { 347 | let (field, r) = row 348 | if (r.always-display) { 349 | true 350 | } else { 351 | problem-list.any(p => p.at(field, default: none) != none) 352 | } 353 | }).map(row => { 354 | let (field, r) = row 355 | (text(r.name), ) 356 | problem-list.map(p => { 357 | let v = p.at(field, default: none) 358 | let w = if (v == none) { 359 | if (type(r.default) == str) { 360 | (r.wrap)(r.default) 361 | } else if (type(r.default) == function) { 362 | (r.wrap)((r.default)(p)) 363 | } else if (type(r.default) == content) { 364 | (r.wrap)(r.default) 365 | } 366 | } else { 367 | v 368 | } 369 | 370 | if (type(w) == str) { 371 | (r.wrap)(w) 372 | } else { 373 | w 374 | } 375 | }) 376 | }).flatten() 377 | } 378 | ) 379 | 380 | [提交源程序文件名] 381 | table( 382 | columns: columns, 383 | stroke: 0.4pt, 384 | align: horizon, 385 | ..{ 386 | languages.map(l => { 387 | if (l.len() == 2) { 388 | l += (1em, ) 389 | } 390 | (text(size: l.at(2))[对于 #l.at(0) #h(1fr) 语言], ) 391 | problem-list.map(p => { 392 | let v = p.at("submit-file-name", default: p.name-en + "." + l.at(1)) 393 | if (type(v) == str) { 394 | raw(v) 395 | } else if (type(v) == function){ 396 | v(l.at(1)) 397 | } else { 398 | v 399 | } 400 | }) 401 | }).flatten() 402 | } 403 | ) 404 | 405 | [编译选项] 406 | table( 407 | columns: columns, 408 | align: (left+bottom, center+bottom), 409 | stroke: 0.4pt, 410 | ..{ 411 | compile-options.map(l => { 412 | if (l.len() == 2) { 413 | l += (1em, ) 414 | } 415 | ( 416 | text(size: l.at(2))[对于 #l.at(0) #h(1fr) 语言], 417 | table.cell( 418 | colspan: problem-list.len(), 419 | raw(l.at(1)) 420 | ) 421 | ) 422 | }).flatten() 423 | } 424 | ) 425 | } 426 | 427 | let next-problem() = { 428 | current-problem-idx.step() 429 | pagebreak() 430 | statement-page-begin.update(it => true) 431 | context { 432 | let problem = get-current-problem(here()) 433 | heading(level: 1, default-problem-fullname(problem)) 434 | } 435 | } 436 | 437 | let filename(it) = { 438 | set text(style: "italic", weight: "bold") 439 | it 440 | } 441 | 442 | let current-filename(ext) = context { 443 | let problem = get-current-problem(here()) 444 | filename(problem.at("name-en") + "." + ext) 445 | } 446 | 447 | let current-sample-filename(idx, ext) = context { 448 | let problem = get-current-problem(here()) 449 | filename(problem.at("name-en") + "/" + problem.at("name-en") + str(idx) + "." + ext) 450 | } 451 | 452 | let data-constraints-table-args = { 453 | ( 454 | stroke: (x, y) => ( 455 | left: if (x > 0) { .4pt }, 456 | bottom: 2pt, 457 | top: if(y == 0) { 2pt } else if (y == 1) { 1.2pt } else { .4pt } 458 | ), 459 | align: center+horizon, 460 | ) 461 | } 462 | 463 | ( 464 | init: init, 465 | title: title, 466 | problem-table: problem-table, 467 | next-problem: next-problem, 468 | filename: filename, 469 | current-filename: current-filename, 470 | current-sample-filename: current-sample-filename, 471 | data-constraints-table-args: data-constraints-table-args 472 | ) 473 | } 474 | -------------------------------------------------------------------------------- /template/color1.in: -------------------------------------------------------------------------------- 1 | 1234567890 2 | 1 2 3 | 3 4 4 | 5 6 5 | 7 8 6 | 9-10-11.12 -------------------------------------------------------------------------------- /template/fig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wallbreaker5th/fuzzy-cnoi-statement/2dba35f564756e33baa93bf30978ec51b6b7ef54/template/fig.png -------------------------------------------------------------------------------- /template/main.typ: -------------------------------------------------------------------------------- 1 | #import "@preview/fuzzy-cnoi-statement:0.1.3": *; 2 | 3 | // 以下有大量 Fancy 的设置项。你可以根据需求,注释掉你不需要的内容,或者将你需要的内容取消注释。 4 | 5 | #let prob-list = ( 6 | ( 7 | name: "圆格染色", // 题目名 8 | name-en: "color", // 英文题目名,同时也是目录 9 | time-limit: "1.0 秒", // 每个测试点时限(会显示为 $1.0$ 秒) 10 | memory-limit: "512 MiB", // 内存限制(显示同上) 11 | test-case-count: "10", // 测试点数目(显示同上) 12 | test-case-equal: "是", // 测试点是否等分 13 | year: "2023", // 你可以添加自定义的属性 14 | ), 15 | // 实际上必需的项只有 name-en 16 | // 下面是一些花活 17 | ( 18 | name: "桂花树", 19 | name-en: "tree", 20 | type: "交互型", // 题目类型 21 | time-limit: "0.5 秒", 22 | memory-limit: "512 MiB", 23 | test-case-count: "10", 24 | test-case-equal: "是", 25 | year: "2023", 26 | // submit-file-name 为提交文件名,可以为 str、content 或一个 extension:str=>content 的函数 27 | // submit-file-name: e => { 28 | // show raw: set text(size: 0.8em) 29 | // raw("tree." + e) 30 | // } // 将其字体变小 31 | ), 32 | ( 33 | name: "深搜", 34 | name-en: "dfs", 35 | type: "提交答案型", 36 | executable: [无], 37 | input: [`dfs`$1~10$`.in`], // 输入文件名 38 | output: [`dfs`$1~10$`.out`], // 输出文件名 39 | test-case-count: "10", 40 | test-case-equal: "是", 41 | submit-file-name: [`dfs`$1~10$`.out`], 42 | ), 43 | ) 44 | 45 | #let contest-info = ( 46 | name: "全国中老年信息学奥林匹克竞赛", 47 | name-en: "FCC ION 3202", // 似乎也可以当成副标题用 48 | round: "第一试", 49 | time: "时间:2023 年 7 月 24 日 08:00 ~ 13:00", 50 | // author: "破壁人五号" 51 | ) 52 | 53 | 54 | #let (init, title, problem-table, next-problem, filename, current-filename, current-sample-filename, data-constraints-table-args) = document-class( 55 | contest-info, 56 | prob-list, 57 | // custom-fonts 参数可以更改字体,字典各项的键值为:mono、serif、cjk-serif、cjk-sans、cjk-mono、cjk-italic,值为字体名。你可以只传入部分项。默认分别为: 58 | // - Consolas 59 | // - New Computer Modern 60 | // - 方正书宋(FZShuSong-Z01S) 61 | // - 方正黑体(FZHei-B01S) 62 | // - 方正仿宋(FZFangSong-Z02S) 63 | // - 方正楷体(FZKai-Z03S) 64 | // header 参数可以自定义页眉,你需要传入一个 (contest-info, current-problem) => content 的函数。 65 | // footer 参数可以自定义页脚,你需要传入一个 (contest-info, current-problem) => content 的函数。 66 | ) 67 | 68 | #show: init 69 | 70 | #title() 71 | 72 | #problem-table( 73 | // 默认会显示以下行(括号内为默认值,打星号的在没有题目有这一项时不会显示): 74 | // - name 题目名称(无) 75 | // - type 题目类型(传统型) 76 | // - name-en 目录 77 | // - executable 可执行文件名(默认为目录名) 78 | // - input 输入文件名(默认为目录名 + ".in") 79 | // - output 输出文件名(默认为目录名 + ".out") 80 | // - * time-limit 每个测试点时限(无) 81 | // - * memory-limit 内存限制(无) 82 | // - * test-case-count 测试点数目(10) 83 | // - * subtask-count 子任务数目(1) 84 | // - * test-case-equal 测试点是否等分(是) 85 | // 86 | // 一般来说,默认显示的行的设置是够用的。但如果你希望增加更多行,或者当你有太多题目需要展示,你可能需要 extra-rows 参数来添加新的行。 87 | // extra-rows 也可以覆盖掉默认的行。其在题目过多、需要将特定行的字体变小时尤其有用。 88 | extra-rows:( 89 | year: ( // 对应的 field 名 90 | name: "年份", // 显示的名字;可以用 content(调整字号等) 91 | wrap: text, // 显示的样式:若题目的这一项是 str,则显示为 wrap(str),否则会直接显示这一项。默认为 text。 92 | always-display: false, // 是否总是显示:若为 false,则至少要有一个题目有这一项才会显示。默认为 false。 93 | default: "2023" // 默认值,默认为“无”。你也可以传入一个函数,其接受一个参数,为当前题目的信息,返回一个 str 或 content。 94 | ), 95 | contest: ( 96 | name: "赛事", 97 | wrap: text.with(fill: blue), // 你也可以在这里设置更小的字体 98 | always-display: true, 99 | default: "NOI" 100 | ), 101 | setter: ( 102 | // name: text(size: 0.8em)[出题人], // 也许你需要更小的字号 103 | name: "出题人", 104 | always-display: true, 105 | default: p => { p.name-en + "的出题人" } 106 | ), 107 | foo: ( 108 | name: "bar", 109 | wrap: text, 110 | default: "这一行不会显示" 111 | ) 112 | ), 113 | // 提交源程序文件名的列表,每一种语言为 (语言名, 文件后缀名) 的二元组,或 (语言名, 文件后缀名, 首列字体大小) 的三元组。若 problem 没有指明 submit-file-name,则用题目英文名与后缀名拼接。 114 | languages:( 115 | ("C++", "cpp"), 116 | ("D++", "dpp"), 117 | // ("D++", "dpp", 0.8em), // 更小的字号 118 | ), 119 | // 各个语言的编译选项,每一种语言为 (语言名, 编译选项) 的二元组,或 (语言名, 编译选项, 首列字体大小) 的三元组。 120 | compile-options: ( 121 | ("C++", "-O2 -std=c++20 -DOFFLINE_JUDGE"), 122 | ) 123 | ) 124 | 125 | *注意事项(请仔细阅读)* 126 | + 文件名(程序名和输入输出文件名)必须使用英文小写。 127 | + C++ 中函数 main() 的返回值类型必须是 int,程序正常结束时的返回值必须是 0。 128 | + 因违反以上两点而出现的错误或问题,申诉时一律不予受理。 129 | + 若无特殊说明,结果的比较方式为全文比较(过滤行末空格及文末回车)。 130 | + 选手提交的程序源文件必须不大于 100KB。 131 | + 程序可使用的栈空间内存限制与题目的内存限制一致。 132 | + 只提供 Linux 格式附加样例文件。 133 | + 禁止在源代码中改变编译器参数(如使用 \#pragma 命令),禁止使用系统结构相关指令(如内联汇编)和其他可能造成不公平的方法。 134 | 135 | 136 | #next-problem() 137 | 138 | == 题目描述 139 | 140 | 输入两个正整数 $a, b$,输出它们的和。 141 | 142 | 你可以*强调一段带 $f+or+mu+l+a$ 的文本*。用 `#underline` 加 ``` `` ``` 来实现 #underline[`underlined raw text`]。 143 | + 第一点 144 | + 第二点 145 | 146 | - 第一点 147 | - 列表可以嵌套 148 | - 但目前,有序列表和无序列表的互相嵌套会有缩进上的问题。 149 | - 第二点 150 | - 第二点的第一点 151 | - 第二点的第二点 152 | 153 | 154 | == 输入格式 155 | 156 | 从文件 #current-filename("in") 中读入数据。// 自动获取当前题目的输入文件名 157 | 158 | 输入的第一行包含两个正整数 $a, b$,表示需要求和的两个数。 159 | 160 | == 输出格式 161 | 162 | 输出到文件 #filename[color.out] 中。 163 | 164 | 输出一行一个整数,表示 $a+b$。 165 | 166 | == 样例1输入 167 | // 从文件中读取样例 168 | #raw(read("color1.in"), block: true) 169 | 170 | == 样例1输出 171 | // 或者直接写在文档中 172 | ```text 173 | 13 174 | ``` 175 | 176 | == 样例1解释 177 | 178 | #figure(caption: "凹包")[#image("fig.png", width: 40%)] 179 | 180 | 如@aobao,这是一个凹包。 181 | 182 | #for (i,case) in range(2, 8).zip(( 183 | $1 tilde 5$, 184 | $6 tilde 9$, 185 | $10 tilde 13$, 186 | $14 tilde 17$, 187 | $18 tilde 19$, 188 | $20$)){[ 189 | == 样例#{i+2} 190 | 见选手目录下的 #current-sample-filename(i, "in") 与 #current-sample-filename(i, "ans")。 191 | 192 | 这个样例满足测试点 #case 的条件限制。 193 | ]} 194 | 195 | == 数据范围 196 | 197 | 对于所有测试数据保证:$1 <= a,b <= 10^9$。 198 | 199 | #figure( 200 | table( 201 | columns: 4, 202 | ..data-constraints-table-args, // 默认的针对数据范围的三线表样式 203 | table.header( 204 | [测试点编号], $n,m <=$, $q<=$, [特殊性质], 205 | ), 206 | $1 tilde 5$, $300$, $300$, table.cell(rowspan:2)[无], 207 | $6 tilde 9$, table.cell(rowspan:4)[$10^5$], $2000$, 208 | $10 tilde 13$, table.cell(rowspan:4)[$10^5$], [A], 209 | $14 tilde 17$, [B], 210 | $18 tilde 19$, table.cell(rowspan:2)[无], 211 | $20$, $10^9$, 212 | ) 213 | ) 214 | 215 | 特殊性质 A: 你可以像上面这样创建复杂的表格。 216 | 217 | 218 | 219 | 220 | 221 | 222 | #next-problem() 223 | 224 | *这是一道交互题。* 225 | 226 | == 题目描述 227 | #lorem(50) 228 | 229 | == 实现细节 230 | 请确保你的程序开头有 `#include "tree.h"`。 231 | 232 | ```cpp 233 | int query(int x, int y); 234 | void answer(std::vector ans); 235 | ``` 236 | 237 | ```bash 238 | g++ count.cpp -c -O2 -std=c++14 -lm && g++ count.o grader.o -o count 239 | ``` 240 | 241 | 我能吞下玻璃而不伤身体。 242 | 243 | - 赵钱孙李周吴郑王,冯陈楮卫蒋沈韩: 244 | - 杨朱秦尤许何吕施张孔。 245 | - 曹严华金魏陶姜戚谢。 246 | - 邹喻柏水窦章云苏潘葛奚。 247 | - 范彭郎鲁韦昌马苗凤花,方俞任袁柳酆鲍史唐费廉岑薛雷。 248 | - 贺倪汤滕殷罗毕郝邬安常乐于时傅皮卞齐康伍余,元卜顾孟平黄和穆萧尹姚邵湛汪,祁毛禹狄米贝明臧计伏成戴。 249 | 250 | == 评分标准 251 | #lorem(50) 252 | 253 | #lorem(100) 254 | 255 | == 数据范围 256 | #lorem(50) 257 | 258 | 259 | 260 | 261 | #next-problem() 262 | == 题目描述 263 | #lorem(50) 264 | 265 | == 输入格式 266 | 从文件 #filename[dfs$1~10$.in] 中读入数据。 267 | 268 | #lorem(50) 269 | 270 | == 输出格式 271 | 输出到文件 #filename[dfs$1~10$.out] 中。 272 | 273 | #lorem(50) 274 | 275 | == 数据范围 276 | 对于所有测试数据保证:$1 <= n <= 10^5$。 277 | 278 | 279 | -------------------------------------------------------------------------------- /thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wallbreaker5th/fuzzy-cnoi-statement/2dba35f564756e33baa93bf30978ec51b6b7ef54/thumbnail.png -------------------------------------------------------------------------------- /typst.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "fuzzy-cnoi-statement" 3 | version = "0.1.3" 4 | entrypoint = "fuzzy-cnoi-statement.typ" 5 | authors = ["Wallbreaker5th"] 6 | license = "MIT-0" 7 | description = "A template for CNOI(Olympiad in Informatics in China)-style statements for competitive programming" 8 | disciplines = ["computer-science", "education"] 9 | keywords = ["CNOI", "OI", "competitive programming"] 10 | categories = ["office"] 11 | repository = "https://github.com/Wallbreaker5th/fuzzy-cnoi-statement" 12 | 13 | [template] 14 | path = "template" 15 | entrypoint = "main.typ" 16 | thumbnail = "thumbnail.png" 17 | --------------------------------------------------------------------------------