NOI 系列赛常见技术问题整理

发布时间:2022-07-02 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了NOI 系列赛常见技术问题整理脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

前言

(2021)(9)(1) 日起,全新NOI Linux 2 正式替代了旧版 NOI Linux,成为 NOI 系列赛的官方比赛环境。

免责声明

  • 本文信息来于 NOI 官网公布的正在实施的技规范,一些选手的实践经验,向 NOI 技术委员会询问得到的回复等,并进行了一定整理和加工,以供各位参赛选手参考。

  • 本文不应被视为对 NOI 官网公布的技术规范的官方解读,官方规范的最终解释权归属 NOI 科学委员会,作者不保证本文的内容完全准确。对于规范中未作出明确规定,不确定性较大的内容,将会用 斜体 进行标注。

  • 因为 NOI 系列赛基本采用无实时反馈的赛制,选手无法通过向 OJ 提交,获得提交反馈的方法测试其代码在官方评测环境下是否正常编译,运行结果是否符合期望。选手应理解这一赛制产生的不确定性,并自行承担相关风险。作者不为任何因这一不确定性造成的成绩波动承担责任。

系统配置情况

NOI Linux 2.0 是基于 ubuntu 20.04 LTS 改造而成的系统,为 (64) 位系统。

系统内自带 g++ 编译器,版本 (9.3.0)(编译时如果未指明语言标准,默认采用 C++14 标准),另外有 Python (2.7)(3.8),虽然 Python 并非竞赛语言,但可以使用 Python 编写一些辅助性程序(如数据生成器,对拍器等)。

IDE 有 Code::Blocks,Geany。

编辑器有 VS Code(安装了 C++ 扩展,但组件不完整,另外简体中文翻译),Vim,Emacs,gedit,Sublime Text (3) 等。

NOI 技术规范摘抄

将现有的技术规范简单整理后做了份简明,方便理解的版本。

请仔细阅读并理解这部分内容后,再阅读下面的部分。不清楚这部分的内容导致的盲目提问可能会给您带来不必要的尴尬

  • 对于一道题目,选手只应该提交一个扩展名为 .cpp 的源文件,且其大小不应超过 (100 operatorname{KB}),不应使用自己编写的头文件。((2022) 年起全部 NOI 系列赛均只能使用 C++ 语言)

  • 选手程序应正常结束,main 函数的返回值为 (0)

  • 选手程序不应执行如下违规操作:

    • 试图访问网络;

    • 使用 forkexecSystem 或其它线程/进程生成函数;

    • 打开或创建题目规定的输入/输出文件之外的其它文件和目录;

    • 运行其它程序;

    • 改变文件系统的访问权限;

    • 读写文件系统的管理信息;

    • 使用除读写规定的输入/输出文件之外的其它系统调用;

    • 捕获和处理鼠标和键盘的输入消息;

    • 读写计算机的输入/输出端口;

    • 禁止使用内嵌汇编;

    • 禁止更改评测时使用的编译选项。

  • 在不违反上述规定的前提下,选手可以自由使用以下划线开头的宏和函数。

我能使用...吗?

  • bITs/stdc++.h:可以使用。需要注意这样会将所有头文件引入,会增大标识符冲突的风险。

  • __int128:现在的系统是 (64) 位系统,因此可以使用。需要注意的是 __int128 并不能直接使用 cin/coutscanf/PRintf 进行输入输出,需要手写输入输出函数(类似于快读快输)

  • __gcd()__builtin_clz() 等一部分下划线开头函数:可以使用(因为没有被禁止的操作)。

  • gets():因为存在缓冲区溢出的问题,已经于 C++11 中被弃用,C++14 中被废除。可以使用 fgets() 替代。

  • itoa():不是标准库中的函数。是否能使用取决于本机能否正常编译。

  • 在代码中手动开启 -O2 等优化选项:不可以。评测时只能按照 PDF 首页给出的编译选项编译程序,擅自更改编译选项属于违例。

  • 指令集:不可以。理由同上。

  • pb_ds:可以使用。

  • 无序关联式容器:C++11 起可以直接使用,C++98/03 时它们在 std::tr1 命名空间下(是否能在比赛中使用 std::tr1 命名空间尚不清楚)。需要注意它们的最坏复杂度是线性的。

  • 基于范围的 for 循环:C++11 起可以使用。

  • auto 类型说明符:C++11 起可以使用。

  • tuple:C++11 起可以使用。

  • 多线程:不能使用。

  • register:C++11 起被弃用,C++17 起被移除。因此 C++11 后使用它不会造成任何优化效果。

  • 列表初始化:C++11 起可以使用。需要注意的是 Windows 下部分编译器在使用 C++11 以前标准编译使用列表初始化的程序时,只给出警告而无错误。更推荐的做法是使用构造函数。

  • 随机函数:没有限制。但 random_shuffle 已经于 C++14 起被弃用,C++17 起被移除。C++11 以后可以使用 shuffle 函数替代。另外有关随机化造成的评测结果波动引发的申诉,按规定将不被接受。

比赛系统的使用

考虑到有不少选手不熟悉 Linux 系统,还有不少地方仍然使用 Windows 作为比赛环境,因此特开辟一个板块,讲解 Linux 与 Windows 的相关使用技巧。

有关 Linux 和 Windows 下命令行使用的相关技巧,OI Wiki 讲述得非常详细,这里主要是介绍命令行使用以外的一些注意事项

更改栈空间

一般来说,评测时的栈空间限制等于内存限制。但系统默认的栈空间往往较小,有时会出现官方评测时正常运行,而本地测试时爆栈的情况。这时候就需要对栈空间进行更改。

在 Linux 系统下,由 ulimit 对程序使用的资源进行限制。

输入 ulimit -s <num> 可以将栈空间更改为 (text{num}) KiB(如 ulimit -s 262144 可以将栈空间改为 (256) MiB),ulimit -s unlimited 可以将栈空间改为无限制。ulimit -a 可以查看各项资源的限制情况。

需要注意的是,ulimit 对包括栈空间在内的资源限制的配置仅在 当前终端 下有效。

对于 Windows 系统,栈空间在程序编译时确定,准确来说,由连接器来处理栈空间的大小问题。在编译时传入如下参数 -Wl,--stack= 可以将栈大小改为 num Byte(如 -Wl,--stack=268435456 将栈空间确定为 (256) MiB)。

查看样例文件

一般情况下,考场下发的样例文件是 Linux 格式的(换行为 n),而 Windows 下的换行为 rn,因此如果用记事本打开的话,因为无法正确识别换行的原因,样例会无法正常显示(可能表现为无换行,换行符被黑矩形代替等)。

使用 VS Code 等高级编辑器可以有效解决这一问题(还能实现换行格式的转换)。当然如果没有提供 VS Code 的话,也可以用系统自带的写字板。

当然这只是解决了显示问题,如果你尝试在写字板打开文件后,将输入直接复制到命令行,你可能会发现还是不能正常读入。正确的方法是在代码中添加重定向/文件流,或者在命令行中使用管道。

参考资料

  • NOI 系列赛常见技术问题整理 - Studying Father's luogu blog
  • [洛谷日报#86]OIer 必知的编程技巧(2018 年的文章,部分内容可能已经过时)
  • 命令行 - OI Wiki

本文搬运自别人持续更新的文章留作自用,如有更新请提醒一下。

脚本宝典总结

以上是脚本宝典为你收集整理的NOI 系列赛常见技术问题整理全部内容,希望文章能够帮你解决NOI 系列赛常见技术问题整理所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。