NOIP注意事项

系统环境

评测环境:NOI Linux 1.4.1

竞赛系统提供Windows和NOI Linux

NOI Linux

分类 软件及版本 说明 启动/使用方法
系统软件 NOI Linux 1.4.1 操作系统 开机自动启动
编译器 GCC 4.8.4 C编译器 终端运行,命令行:gcc test.c -o test
G++ 4.8.4 C++编译器 终端运行,命令行:g++ test.cpp -o test
FPC 2.6.2 Pascal编译器 终端运行,命令行:fpc test.pas
调试器 GDB 7.7.1 命令行调试器 终端运行,命令行:gdb
DDD 3.3.12 终端运行,命令行:ddd
集成开发环境 GUIDE 1.02 单文件程序 鼠标点击启动: 应用程序→编程→GUIDE
Anjuta 3.10.2 C/C++ IDE 鼠标点击启动: 应用程序→编程→Anjuta IDE
Lazarus 1.0.12 Pascal IDE 鼠标点击启动: 应用程序→编程→Lazarus
编辑器 vim 7.4 文本编辑器 终端运行,命令行:vi
GNU Emacs 24.3.1 鼠标点击启动: 应用程序→编程→Emacs24
gedit 3.10.4 鼠标点击启动: 应用程序→附件→文本编辑器

Windows

各省情况不同

2018年山西省提供Windows7 Home Basic

分类 软件及版本 说明
系统软件 Windows7 Home Basic x86 操作系统
集成开发环境 Dev-C++ 5.9.2 C/C++ IDE
Free Pascal IDE Pascal IDE
编辑器 Notepad++ 7.4.1 文本编辑器
Sublime Text

答题

文件名

文件名建议直接复制题目,不建议手打。

复制的时候注意行末尾不要有空格。

输入输出文件名要写对了!

C语言源代码文件必须以.c结尾,C++源代码文件以.cpp结尾,Pascal源代码以.fpc结尾。

头文件

一定写全了,慎重使用bits/stdc++.h

cstdio必须写(freopen)

使用memset必须写cstring

min、max、sort、lower_bound、max_element这些必须写algorithm

vector、stack、queue、priority_queue要写上相应的头文件。

使用pbds库需要写上对应的头文件。

输入输出

文件输入输出。

1
2
freopen("input.in","r",stdin);
freopen("output.out","w",stdout);

注意输入输出规模,cin和cout比较慢,可以使用关闭流同步提速

1
std::ios::sync_with_stdio(false);

注意:关闭流同步的cin、cout不可用和其他的输入输出方式混用!!!

建议直接用scanf即可。

当然也可以手写快读:

1
2
3
4
5
6
void read(int &x)
{
int f=1;x=0;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();x*=f;
}

编译

建议添加题目描述中所给的所有编译选项。

1
g++ std.cpp -o std

强烈建议加上-Wall

千万不要把编译命令写成

1
g++ std.cpp -o std.cpp

这个后果有非常惨,poorpool亲身经历。会覆盖掉你的代码!!!

为了保险,提交之前使用以下命令编译一次确认无误

1
g++ std.cpp -o std -lm -Wall -std=c++98

调试

Windows选手可以使用Dev-C++的断点调试。

Linux选手可以使用调试器(然而我并不会用)

当然最朴素的方式还是直接输出过程量了。

建议使用cerr输出调试。

1
cerr<<a<<' '<<b<<' '<<c<<endl;

注意最后一定要删掉所有的调试信息。

对拍

可以手写对拍器。

个人习惯直接用cpp写对拍。

说一下Windows下的对拍方法。

首先,新建一个文件夹,

然后,在里面放入std.exe,和test.exe,还有data.exe

std.exe是你暴力写的一个做法生成的程序,反正结果肯定是对的。

test.exe就是你的代码生成的程序,你不知道他对不对或者你知道他是WA的但是你不知道哪里WA了。

data.exe就是你的数据生成器,你可以用它去生成你认为的合法数据。

std.cpp

1
2
3
4
5
6
7
8
9
10
#include <iostream>
using namespace std;

int main()
{
int a,b;
cin >> a >> b;
cout << a+b << endl;
return 0;
}

test.cpp

1
2
3
4
5
6
7
8
9
#include <cstdio>

int main()
{
int a, b;
scanf("%d %d",&a, &b);
printf("%d\n", a+b);
return 0;
}

data.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream> 
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <fstream>
#include <algorithm>
#include <windows.h>
using namespace std;
int main()
{
truesrand(time(0));
trueint a,b;
truea=rand()%100+1,b=rand()%100+1;
trueprintf("%d %d\n",a,b);
truereturn 0;
}

方法一(这个比方法二运行起来更快一点):

新建一个 gen.bat

内容为

1
2
3
4
5
6
7
:again
data > input.txt
std < input.txt > std_output.txt
test < input.txt > test_output.txt
fc std_output.txt test_output.txt
if not errorlevel 1 goto again
pause

方法二:

写一个gen.cpp然后编译运行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include<iostream>
#include<windows.h>
using namespace std;
int main()
{
int t=1000;
while(t)
{
t--;
system("data.exe > input.txt");
system("std.exe < input.txt > std_ans.txt");
system("test.exe < input.txt > test_ans.txt");
if(system("fc test_ans.txt std_ans.txt")) break;
}
if(t==0) cout<<"no error"<<endl;
else cout<<"error"<<endl;
return 0;
}

技巧

  1. 对于long long这类过于长的变量名,多次使用很浪费时间。可以使用以下方式自定义类型。

    1
    2
    typedef long long LL; //自定义类型LL为long long
    LL a,b;//long long类型的变量a和b
  2. 重载运算符

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    struct node
    {
    int a,b,c;
    bool operator <(const node &other) const
    {
    return this->c < other.c;
    }
    //重载<运算符

    node operator *(const node &other) const
    {
    node ans;
    ans.a = this->a * other.a;
    ans.b = this->b * other.b;
    ans.c = this->c * other.c;
    return ans;
    }
    //重载*运算的符
    };
  3. 数据分治使用namespace

    1
    2
    3
    4
    5
    6
    7
    8
    namespace score20
    {
    true//写20分做法
    }
    namespace score50
    {
    //写50分做法
    }

    这样可以使得思路清晰,也可以避免变量名混乱。

  4. 关于多组数据

    • 给定了数据组数的

      1
      2
      3
      4
      5
      6
      7
      int T;
      scanf("%d",&T);
      while(T--)
      {
      init();//每次一定要初始化
      work();
      }
    • 没有给定数据组数

      1
      2
      3
      4
      5
      while(scanf("...",...)!=EOF)
      {
      init();//初始化
      work();
      }

    一定要初始化!初始化!初始化!

  5. 离散化去重

    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include<vector>
    #include<algorithm>
    std::vector<int> number;
    int main()
    {
    std::sort(number.begin(),number.end());//排序
    std::vector<int>::iterator End=std::unique(number.begin(),number.end());//去重
    return 0;
    }

注意事项

  1. 文件名和输入输出文件名一定写对了,必须区分大小写。
  2. 数组开够了,不要过大也不要过小,一般比题目数据范围大10左右。
  3. 注意数据范围,合理使用int和long long,有时候数据范围在int范围内不见得计算过程在int范围内。
  4. 写链式边表注意边的数量,双向边开2倍。写线段树开4倍数组。
  5. 合理选择DFS和BFS,DFS有爆栈风险。
  6. 格式化输入输出,long long使用%lld,unsigned long long使用%llu。
  7. 能用double尽量都用double,不要用float。
  8. 对代码进行大规模修改时候建议先备份代码。
  9. 对于取模运算,要在每一步都取模,不能只对结果取模。
  10. 遇到减法取模要先加上模数在取模,以防出现对负数取模导致RE。
  11. 取模运算对除法不封闭,一定要写逆元!!!
  12. 一定写上文件读写,注意文件名(后缀名一定要写上)和模式。
  13. 使用编译选项-Wall以显示最多警告。留意警告内容并注意改正。
  14. 谨慎使用bits/stdc++.h和using namespace std。
  15. Windows选手注意换行符问题,Linux下的换行符是\n。
  16. 千万不可以使用下划线开头的函数,自己写的除外。
  17. 禁止内嵌汇编。
  18. 万一出现机器故障举手示意,不要自行解决。
  19. 不要使用map、count、y1、y2、next之类的关键词作为变量名。

提交

ftp提交

保管好下发的密码条。

Windows选手打开资源管理器,在路径栏里面输入ftp地址。

Linux选手打开资源管理器,连接到服务器。

遇到提交问题可以举手向监考老师求助!

文件名、文件路径

注意,一定要按照题目规定的文件名命名。

注意文件路径,一定要建子文件夹!!!

不建子文件夹会爆0的!!!

确认提交

最后一定要确认自己的程序无误提交。

到教师端查看是否提交成功并签字。

交回密码条!

最后祝大家NOIP2018 RP++,多多AC!

by ACCEPT
2018年11月8日