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 程序