NOI Linux 2.0 食用指南
本文于 2021/9/21 重写
0. 关于终端
打开 NOI Linux,按 Ctrl+Alt+T
,就会弹出来一个窗口,这就是 Linux 下的终端,NOI Linux 中使用的终端是 bash
大概长这个样子↑
可以在右上角的 Preferences 中的 Profiles 一栏中设置终端的颜色和主题
比如可以把这玩意搞成透明的,颜色也整好看一些↑
这里的终端可以理解为和系统文字交互的窗口,好处是非常灵活,功能强大
1. 基本命令和 Tab 使用技巧
使用 ctrl+C
可以杀掉当前终端运行的程序,会显示为 ^C
0. 终端下的文件系统
注意所有的斜杠都是 /
打开终端,默认的位置是 ~/
,也就是 /home/$USERNAME/
,可以理解为用户的主文件夹,文件系统的 GUI 的主文件夹就是这个玩意
.
表示当前文件夹,可以试一试 ls
和 ls .
的结果是一样的,运行程序的之后也要写 ./exe
,就是为了让文件系统找到当前文件夹
..
表示父文件夹,就是上一级文件夹
/
表示根目录,但用不到,所以不过多介绍
和我们常常理解的文件路径一样,终端中的路径也是由 文件夹/文件夹/.../文件(夹)
组成的
特别地,如果你在第一个文件夹前面没有加上 /
或 ~/
,那么就会在当前目录中的子文件夹中开始寻找,否则就会从 根目录/主文件夹 开始找
1. 进入目录 cd
用法:cd 文件夹
,注意一定要是一个文件夹,按照我们上面的路径形式
2. 列表 ls
ls 是 list 的缩写
用法 ls [目录,默认为 .] [参数]
,即在参数的要求下列出给出目录下所有文件
主要有用的参数是 -l
,会显示所有文件/文件夹的权限、大小等信息
最左边是权限系统,具体我也不太懂,大概就是有 d
的是文件夹,剩下的有 x
的是可执行,rw
分别表示读写权限
中间是作者,然后是大小 (Byte),然后是修改时间
绿色的是可执行,蓝色的是文件夹,白色的是普通文件
3. 建立文件夹 mkdir
mkdir 是 make directory,即创建目录的缩写
用法是 mkdir 文件夹名
,会在当前文件夹下面建一个子文件夹
4. 拷贝文件 cp / 删除文件 rm
cp 是 copy 的缩写,rm 是 remove 的缩写
cp [参数] 文件 目标位置/文件
,将文件考到目标位置下(保留原来名字)或拷到文件的文件夹下,该名叫文件。需要注意的是默认参数是 -f
,即拷贝文件,如果要拷贝文件夹就要用 -r
,而不管是不是文件夹都拷贝用 -rf
rm [参数] 文件/文件夹
同理,删除指定文件夹或文件,要加 -f
、-r
或 -rf
5. 移动/重命名 mv
mv 是 move 的缩写
mv 旧文件 新文件
,注意这里旧文件和新文件可以包含路径
6. 内置比较命令 diff/cmp
diff 是 differance 的缩写,获取两个文件的不同,基本会使用 diff 文件 文件 -Z
来比较两个文件,其中 -Z 表示忽略空格和换行(由于换行 windows 和 linux 可能不同)
cmp 是按字节比较两个文件
7. 打印到终端 cat
我也不知道为啥叫 cat
cat
会重复输入的内容
可以给 cat
后面跟文件,也可以重定向输入输出(后面会讲)
2. 在终端下编译、运行程序
使用 g++ 编译
NOI 系列赛、CSP 使用的都是 gcc,或者叫 g++,NOI Linux 2.0 上代的是 9.3.0,默认 c++ 版本是 c++14
试试在终端里输入 g++ --version
,他会告诉你这是 9.3.0 版本的
g++ 的用法是 g++ [参数] ... [参数] 源文件 ... 源文件 [参数] ... [参数]
常用的参数包括:
-o exename
:将输出的可执行文件输出到 exename-lm
:使用 cmath 必须要加-Wall -Wextra
大概全部/额外警告-O0/O1/O2/O3/Ofast
:开启对应优化-std=c++xx
:使用 c++xx 标准,其中 xx 可以使 98/11/14/17-fsanitize=address,undefined
:开启 ason,可以帮助你解析越界或UB行为,注意会让你的程序变慢
运行程序
只需要一行:文件名称
,注意这里需要包含所在文件夹,比如当前目录下有 a.exe
,直接输入 a.exe
会报错,必须是“当前文件夹”下的 a.exe
才可以,所以要用 ./a.exe
3. 程序运行的计时、重定向输入输出、对拍
给终端上运行的程序计时
在运行文件命令前面加上一行 time
就可以得知程序占用的时间(系统时间/用户时间)
在运行文件命令后使用 < 文件
和 > 文件
可以重定向 stdin/stdout
,即 stdin
或 stdout
从指定文件而不是终端读取/写入,可以自己进行尝试
生成随机数
一般我们在生成随机数的时候都会用 srand(time(0))
或 srand(clock())
配合 rand()
生成随机数,但 time()
和 clock
的计时精度不高,导致拍了很多组生成的随机数据都是一样的,c++11
之后有了 std::mt19937
的随机数生成器和 std::chrono
的高精度计时器,所以我们可以这样写:
std::mt19937 mtrnd(std::chrono::system_clock::now().time_since_epoch().count());
后面的计时器是微秒级的,而 mt19937
的循环节非常长,非常随机,而且得到随机数的话是 ll 类型,可以直接用 mtrnd()
调用随机数
对拍
下面给出我写的一个对拍
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
cout << fixed << setprecision(15);
cerr << fixed << setprecision(15);
int t = 1e6;
for(int i = 1; i <= t; i++) {
cerr << "test #" << i << "... ";
system("./gen.exe > in");
system("./std.exe < in > ans");
system("./sol.exe < in > out");
if(system("diff -Z out ans")) {
cerr << "WA!" << "\n";
return 1;
}
cerr << "AC!" << "\n";
}
return 0;
}
使用 system()
函数可以视作在终端下执行对应的命令,而 diff
和 cmp
命令是有返回值的,不一样即为 1,所以就可以这么写
4. 使用终端召唤编辑器(emacs/gedit)
可以试试 emacs b.cpp &
,会新建一个空的文件,而在弹出来的窗口里编辑好点击保存之后,当前文件夹会多出一个 b.cpp
的文件,内容刚好是刚刚编辑的内容
(咕着先