OI 中的一些技巧

前言:可能写的很乱,博客中的问题请尽管指出,后面会整理。
参考博客:

命令行

命令行可以简单理解成不带图形化需要输指令的工具。
Windows 中有 cmd(和更加强大的 PowerShell),Linux 中有 bash。
由于 OI 中命令行的使用大同小异就一块讲了。

打开

Windows 的 cmd 可以摁快捷键 win + r,然后输入 cmd,回车即可。
或是开始菜单的“Windows 系统”→命令提示符。
文件资源管理器输入 cmd,回车。
你甚至可以跑 C:\Windows\System32 里面打开。
Linux 摁下 Ctrl + Alt + T 即可。

编译

准确来说编译并不是命令行的功能,但是搭配命令行会非常方便。
OIer 编译 C++ 程序一般都会用 Mingw64 中的 g++.exe 对 cpp 源文件编译。
完整的编译指令大约是这样的。(以 cmd 为例)

D:\mingw64\bin\g++.exe C:\Users\LiJoQiao\Documents\P1001.cpp -o C:\Users\LiJoQiao\Documents\P1001.exe -O2 -Wall -Wextra -std=c++14

(虽然因为太长显示用了两行,但是写的时候我确实写在了一行)
Linux 大同小异,在引用文件的地方多了"./"而已。

上面的指令先打开了一个路径中的 g++.exe,然后填写了编译的 cpp 源文件,后面全部都是编译选项。
-o 是用来指定编译出的程序名称的,后面紧跟路径和名字。
-O2 是开 O2 优化。
-Wall -Wextra 对代码对代码可能错误有风险的地方进行警告。
-std=c++14 是用了 c++14 标准,标准可以按需求使用。
可以参考一下这个:GCC常用编译选项
编译选项大家可以自己找下资料,OI 中上面的够用了。

这样写起来未免有亿点长,我们可以简化一下路径。
可以看看这篇文章:相对路径和绝对路径?简洁易懂解释+实例
上面写的都是绝对路径,这个就是最原始的路径,可以理解从磁盘开始,跟着走肯定不会错的路径。
我们可以使用相对路径来简化,相对路径就是相对某个位置下的路径。
如果你现在亮着桌面,有人让你打开浏览器,你也许就直接移动鼠标双击了 Chrome 的快捷方式。
相对路径也是一样的道理,你的命令行上都有显示它现在所在的路径(如下图红圈)。

在这里你输入一个它路径下的程序的名称,它就可以直接调用这个程序。
相对路径可以是环境变量中的 Path 或是程序所在位置等。
下面讲如何使用相对路径。

对于编译器 g++.exe,我习惯于设置 Path 来使用其的相对路径。
设置环境变量的步骤十分简单,这里不详细说了,放出两篇文章。
windows10设置环境变量Path详细步骤
Win10怎么配置环境变量path?
顺带一提,win7 的环境变量只会让你填一行,这时候你在原来堆一块的路径上用分号隔开,然后再写上,这样可以避免丢失原来的相对路径。
win10 就不要管了,你新建了这个之后它会自动给你整好。
也不要担心在考场上不会设置,因为 CCF 一般会给你配好环境变量。

你也可以更改命令行的所在位置。
我一般用来打开源文件的位置。
如何将命令行的路径改变呢?
在文件资源管理器打开一个磁盘/文件夹后,在上面的路径输入 cmd,回车,即可打开路径在这个磁盘/文件夹下的 cmd。
或者你用 cd 指令(Linux 也可以),后面跟需要的路径,回车即可更改。

这样我们再写上面的编译指令,只需像下面一样简短。

g++.exe P1001.cpp -o P1001.exe -O2 -Wall -Wextra -std=c++14

补充

你也可以用与 g++.exe 同一路径下的 size.exe,这个程序后面跟上你要测试的 exe 程序,可以测出你的静态空间大小(全局变量、数组之类的,vector 等容器、局部变量不能检测的到)。

调试、对拍

你也可以用上面的相对路径打开你的程序,使用命令行打开程序后你可以在命令行里进行输入输出,与 Dev-C++ 的控制台类似。
当然加了 freopen 之后肯定是不行的。
很多时候我们考试手里都会有很多大样例(迫真),然而我们不想自己龟速的改 freopen 编译运行。
可以用到命令行的重定向,使程序的标准输入输出改变到文件。
如果上面那句看不懂,你可以简单理解为它有 freopen 的功能,但是和 freopen 不是一个东西,不需要编译。
这个重定向操作在源代码加了 freopen 后是不起作用的,我们需要在程序中注释掉然后编译。
现在我有一个 P1001.in 和 P1001.ans,放在 P1001.exe 的同一路径下,我想使标准输入重定向到 P1001.in,标准输入到 P1001.out。
可以使用下面的指令。

P1001.exe < P1001.in > P1001.out

< 后面跟上要输入的文件,> 后面跟上要输出的文件,这样 P1001.out 就是输入了 P1001.in 的结果。
两者并不是要绑定在一块的,你可以单独用 <,也可以单独用 >,甚至都不用或都用。
(顺带一提,Linux 甚至可以通过这个方法新建一个文件)
我还想让 P1001.out 和 P1001.ans 作比较。
这时可以使用下面的指令(上为 Windows 的cmd,下为 Linux 的bash)。

fc P1001.out P1001.ans
diff P1001.out P1001.ans

这样在命令行里就会告诉你文件是否相同,也就是我们常说的对拍的比较文件的环节。
这样一点点手敲是不是有点麻烦,还不如 freopen
其实没必要手敲,在命令行中摁方向键 可以调用之前的输入过的命令。
如果你有很多样例,你一般只需要修改之前命令中的文件的数字即可。
如果你还需要调程序,调完之后直接摁 直到关于这个程序的第一条命令,然后无脑 Enter 即可。
这样确实比 freopen 的编译快多了。
值得一提的是,交代码的时候记得把 freopen 写回来。

下面讲下如何自己造数据对拍。
首先你需要一个绝对正确的暴力程序,自己写好的正解程序,和一个造出合法数据(数据范围最好既足够强大检查错误,也可以让暴力跑完)。
然后还要一个依次执行造数据程序,暴力和正解,检查错误的对拍程序。
Windows 和 Linux 的对拍程序略有出入,此处分开讲。

Windows 系统

可以用 cmd 或 C++ 程序作为对拍程序。
Oier 选择一个自己习惯的写法即可,不要因噎废食。
以下为 cmd(::后面是注释的内容):

echo off ::不显示执行的命令
:loop    ::循环开始的地方
rand.exe ::造数据
bf.exe   ::暴力程序
sol.exe  ::正解程序
fc data.ans data.out ::比较输出是否一样
if errorlevel == 1 pause ::如果不同则暂停
goto loop::回到循环开始的地方

你需要创建一个后缀为 .bat 或 .cmd 的文件,在里面编辑上面内容(注释就别打了),保存,一个 cmd 程序

posted @ 2023-11-13 10:01  LiJoQiao  阅读(76)  评论(0编辑  收藏  举报