怎样使用NOI Linux编程

2021年10月2日 | 分类: 【编程】

【介绍】

经过多轮开发和内部测试,NOI Linux 2.0版(Ubuntu-NOI 2.0版)已经基于Ubuntu 20.04.1版定制完成,现正式对外发布。
根据NOI科学委员会决议,该系统将自2021年9月1日起作为NOI系列比赛和CSP-J/S等活动的标准环境使用。在此日期前,NOI相关活动标准环境仍为旧版NOI Linux。

系统下载链接:NOI Linux 2.0版(注意:安装系统时请断开网络)
下载:https://noiresources.ccf.org.cn/ubuntu-noi-v2.0.iso

安装教程:https://aiolia.org/noi-linux-win

系统:
Kernel 5.4.0-42-generic 64位

语言环境:
GCC 9.3.0 C编译器
G++ 9.3.0 C++编译器

调试工具:
GDB 9.1
DDD 3.3.12

集成开发环境:
Code::Blocks 20.03 C/C++集成开发环境

文本编辑工具:
VS Code 1.54.3
Emacs 26.3
Gedit 3.36.2
Vim 8.1
Joe 4.6
nano 4.8
sublime text 3.2.2

其他软件:
Firefox 79.0 网页浏览器
Midnight Commander (mc) 4.8.24 终端
XTerm (UXTerm) 3.5.3 终端
Arbiter-local 1.02 程序评测工具单机版

【使用】

先进入虚拟机(即:NOILINUX系统)才能使用以下条件

先点开终端按Ctrl+Alt+t 就出现终端窗口

先输入ls

找到文本目录,比如存放到Desktop(桌面)……

再输入cd Decktop 就能直接到桌面里找文件

在输入 vim a.cpp 就能进入a.cpp内

按Esc键及Shift+冒号 及wq 就能回到终端

再输入g++ -Wall a.cpp -o a (注:W为大写)就能生成a.out文件

最后输入 /.a 即可就能输入数据测评。

参考:https://www.cnblogs.com/ww3113306/p/9795485.html

linux环境下的基础操作
命令行操作
1,使用Ctrl + Alt + T召唤出终端。
2,基础指令:
1,cd
使用方法:cd + 文件目录
效果:使终端所在的目录切换到指定文件目录,但是每次cd只能不断深入某个文件夹,如果要退出这个文件夹则直接使用cd,后面不加任何东西
如果文件名太长懒得打的话,可以打一半然后按Tab键,如果这时你给出的部分文件名已经可以使电脑确定出唯一的一个文件的话,那么将会自动补全这个文件名,否则会给你列出可能的文件名。
2,l
列出当前目录下的文件和文件夹,一般和cd配合使用。
3,./ 程序名
用来运行一个程序
4,> 和 <
有时候你并没有在程序中打文件输入和输出,然后你需要使用文件输入输出,但是又懒得打文件输入输入+重新编译。
这个时候使用这个指令就很方便。
./work < in.in > out.out表示运行work文件,从in.in中读入,输出到out.out中。

编辑器
1,gedit的使用
gedit是我常用的编辑器,基础功能都有,界面比较简洁,因为noi linux下默认打开.cpp文件的软件是emacs,所以如果要使用gedit的话,建议先新建一个.cpp文件,然后右键选择打开.cpp的软件,选文本编辑器(gedit),然后就会默认使用gedit打开.cpp文件了。
一般来说,打开gedit后第一反应应该是进行一些基础的设置。
这里推荐的设置是:

选择编辑,打开首选项:
1,勾选显示行号.
2,勾选右边对齐线显示的位置.(这个一般用于提示自己每行的代码不要过长,会使得代码美观一点)
3,勾选突出显示当前行.(方便定位当前光标所在的位置)
4,勾选突出显示匹配的括号.
5,勾选启用自动缩进.
6,勾选在保存前创建备份文件(每次都选了,但是从来没用到过,以防万一吧)。
7,配色方案我喜欢用暗色的,感觉光线柔和一点,这个根据个人喜好选择即可.

设置完后关闭首选项。点击F9,然后切换到文件浏览器模式(我用的ubuntu16.04,叫法可能不同,但差别不会很大)。这个模式有什么好处呢?
1,你可以直接右键在当前目录下进行新建文件等一系列关于文件的操作(但是好像不能复制粘贴文件),而不需要再打开文件夹进行一系列操作。
2,你可以直接右键在当前目录下调出命令行,从而避免繁琐的cd操作,尤其是在有中文目录的情况下这个会很实用。
3,可以快速切换到当前目录,还可以快速打开当前目录下的文件夹。

1,如果要快速上下翻动可以关闭数字锁定,然后利用小键盘快速翻动,1,7分别对应翻到底部和翻到顶部。2, 8则是小幅度的翻动,3和9是较大幅度的翻动。
2,gedit自带替换的功能(Ctrl + H),这个功能一般用于你之前使用了某个变量名,而你现在又想使用这个变量名,这时你可以用这个功能快速替换之前的同名变量,避免名字冲突。
3,gedit的搜索功能(Ctrl + F),搜索了之后会高亮匹配项。为了防止误选建议勾选区分大小写和匹配整个单词。
4,快速跳转到某一行(Ctrl + I).
以上快捷键根据版本不同,可能略有区别,如果不能使用就在上面的搜索选项中查看对应快捷键即可。
5,你也可以在终端中使用gedit + 文件名来快速创建一个文件,并在gedit中打开。

程序编译
最基础的编译命令:g++ 1.cpp
编译出来的文件叫做a.out
使用./a.out可以运行这个程序。
当然还有一些额外的常用指令,使用的时候直接加在后面即可。
1,-o
可以让你命名编译出来的文件,比如g++ 1.cpp -o work可以使得编译出来的文件叫做work
2,-Wall -Wextra
这两个指令的作用差不多,可以给你一些额外的警告和提示,用于避免一些NC错误。
比如当你在if的判断条件中把x == y写成了x = y时它就会警告你。但这两个指令带来的警告不会使编译失败。
3,-O2
顾名思义,开启O2选项,O2是一种更高级别的优化,平时默认是O1,如果在没有开O2的情况下,大多数STL会跑得很慢(sort之类的除外)。
4,-g
开启gdb
以下是一个示例:(编译1.cpp为work,并运行此程序 同时开启O2优化)

g++ 1.cpp -g -Wall -Wextra -o work -O2
./work

5,文件调用。
这个应该都会吧,一般都是使用freopen来实现文件调用。

int main()
{
    freopen("in.in", "r", stdin);
    freopen("out.out", "w", stdout);
    pre();
    build();
    work();
    fclose(stdin);
    fclose(stdout);
    return 0;
}

程序调试
gdb的使用
gdb是一个功能很强大的调试软件,一般来讲是用于动态调试,跟devc++的单步跟踪差不多,但功能更多,更稳定。因为使用gdb时往往需要一步步的查看程序运行的情况,所以可能调试起来会比较慢,但可以通过一些小技巧来加快调试速度,这个可以自己体会&总结。
首先是一些基础操作;
还有一些不常见操作;

对拍
有时候你打出了一道题的正解,但你可能并不放心你的正解是否是正确的,这时一个很常见的验证方法是对拍。
首先你需要以下程序:
1,正解(或者是一些针对部分数据的高级暴力也是可以的)
2,暴力
3,造数据的程序
4,对拍程序
正解和暴力怎么写就看你自己了,这里简单讲一下如何造数据和写对拍

造数据程序:


#include<bits/stdc++.h>
using namespace std;
#define R register int
int main()
{
    freopen("in.in", "w", stdout);
    srand(time(0));
    int n = rand() % 1000 + 1, m = rand() % 1000 + 1;
    n = 1000, m = 1000;
    printf("%d %d\n", n, m);
    for(R i = 1; i <= n; i ++) printf("%d ", rand() % 50000 + 1);
    printf("\n");
    for(R i = 1; i <= m; i ++)
    printf("%d\n", rand() % n + 1);
    fclose(stdout);
    return 0;
}

这是一份造数据的程序,首先一般会写一个文件输出,表示造出的数据放入要某个文件里。
srand();是给rand()指令重新指定一个种子,否则你将会每次都造出一样的数据,因为rand实际上是通过一个式子不断的计算得到随机值(不是真随机),所以如果种子一样,那么随机出来的东西也将是一样的。
然后中间的就根据题目的输入格式自己写了。
一般在开始会在题目给点范围内随机一个数据大小,但是有时候为了特殊目的(想测极限数据,要用小的错误数据调试等),可能会在下面强制指定一个数据大小。如上面程序中的n = 1000, m = 1000;

对拍程序:

#include<bits/stdc++.h>
using namespace std;
#define R register int

int main()
{
    for(R i = 1; i <= 1000; i ++)
    {
        system("./make");
        system("./work > out.out");
        system("./work1 > out1.out");
        if(system("diff -bB out.out out1.out"))
        {
            printf("error in %d\n", i);
            return 0;
        }
        else
        {
            printf("passed... %d\n", i);
            system("sleep 1");
        }
    }
    return 0;
}

对拍一般都是一样的,所以不会的话背下代码即可,当然理解一下就更好记了。
system();中的指令会起到跟你在终端中输入这串指令一样的效果。
diff -bB out.out out1.out是在忽略行末空格和换行的情况下对比两个文件,如果不同的话会给你返回一个非0的值,因此如果不同的话就输出错误并终止程序,这样的话你就可以保留使你错误的那个数据点。
否则的话输出passed… 当前数据点。提示你过了这个点。
因为一般都是写的srand(time(0));所以如果时间是一样的话,种子也会是一样的,随机出来的东西也会是一样的,所以这个时候多次对同一组数据进行测试就没有意义了。所以一般会使用sleep命令来延迟一秒的时间以满足每次测试的时候种子都不同。

快速编译程序:

这个可能比较冷门,有时候会比较方便。

#include<bits/stdc++.h>
using namespace std;
string name, tmp, s;
int main()
{
    cin >> tmp >> name;
    s = "g++ " + tmp + ".cpp -g -Wall -Wextra -o " + name;
    system(s.c_str());
    return 0;
}

运行这个程序,然后输入你要编译的文件名+你要编译为的程序名,就可以快速将这个文件编译为指定程序名。从而避免每次都要打一长串编译命令。

原文:https://zhuanlan.zhihu.com/p/390523502

杨博洋 计蒜客 CTO

在 2021 年 7 月 16 日,CCF 在官网上发布了 NOI Linux 2.0(NOI Linux 2.0 发布,将于 9 月 1 日起正式启用),时隔三年再次更新了 NOI Linux 环境。此次更新不可谓不大,从原来的 Ubuntu14 直接升级到了 Ubuntu20,并且将系统中饱受诟病的 GUIDE 移除了,取而代之的是在 ICPC 赛事中地位稳固的 codeblocks。当然最最最最最最重要的,是升级了 gcc/g++ 版本,9.3.0 的新版本的默认 C++ 版本是 C++14,CCF 系列赛喜迎现代 C++ 语法。

首先来看安装界面,这次更新在安装界面中也嵌入了 NOI 元素。当然,和最终的使用关系并不大,而且看起来也比较朴实无华,重点帮助安装者记忆 NOI 的全称(总有其他竞赛的同学问为什么全国信息学决赛的首字母不是 C,一看便知)。
NOI Linux 2.0 安装界面

安装完毕后,直奔桌面设置,看一看传说中征集的桌面们长什么样。
默认是最朴素的一张

我个人比较喜欢下面这张(比较花哨),所以就切换成这张了。
里面有历年 NOI 大赛 Logo

接下来就是看看预装了哪些软件,可以看出这次 CCF 还是用心的,去掉了 GUIDE,提供了 Codeb::Bocks IDE,以及 VSCode 和 Sublime 两款编辑器。
Code::Blocks 的时代来了!
预装了 Sublime 以及一系列办公编辑软件
竟然预装了 VSCode,意料之外

接下来是最最最最重要的,gcc/g++ 升级到了 9.3.0,C++ 默认版本为 C++14。
C++14 你好,C++03 再见

因此,我们可以愉快地用 C++11/14 的语法写程序了!写两个试试看。
auto 和 range loop 特性
lambda 表达式

当然,Arbiter 还是在的,看起来功能跟之前也没什么区别,不过毕竟现在系统里自带 Python3,用脚本进行自测已经足够方便了,而集中评测使用 Windows 上的软件在平时练习时也没太大差别。
熟悉的界面,熟悉的味道

以上是对于 NOI Linux 2.0 的试用体验。总而言之,让我们告别 C++03 和 GUIDE,喜迎 C++14Code::Blocks 吧!