一、使用文件读写
在我们的OJ中提交代码,不需要考虑文件读写,但是在信息学奥赛中,代码这样提交时会爆0的。因为信息学奥赛要求从文件中读取测试数据,包括输出数据和输入数据。比如某个题目中会提示:

为了满足上述读取测试文件的要求,只需要将代码修改为:
#include<stdio.h>
int main(){
//在数据输入前,定义读写文件,写在main函数中的所有代码之前
freopen("work.in", "r", stdin); //测试输入数据文件名work.in
freopen("work.out", "w", stdout); //测试输出数据文件名work.out
int a,b;
scanf("%d%d",&a,&b);
printf("%d+%d=%d",a,b,a+b);
return 0;
}
使用cin、cout也是同样处理:
#include<iostream>
using namespace std;
int main(){
//在数据输入前,定义读写文件,写在main函数中的所有代码之前
freopen("work.in", "r", stdin); //测试输入数据文件名work.in
freopen("work.out", "w", stdout); //测试输出数据文件名work.out
int a,b;
cin>>a>>b;
cout<<a<<'+'<<b<<'='<<a+b<<endl;
return 0;
}
通过以上修改,你提交的代码会从work.in文件中读入测试输入数据,并且在运行结束时将输出结果写入work.out文件中。所以,你需要自己写一个测试文件work.in来测试你的代码。(注意:输入输出文件和代码要放在同一个目录)
work.in文件可以用文本编辑工具编写,也可以在代码编辑工具中编写,保存方法如下图所示。(保存类型选全部类型,文件的后缀名.in是我们自己写的)

输入文件中写好你设计的测试数据就可以开展测试了。代码运行后,在work.out文件中检查输出结果是否和你预期的一致。

在linux中,我们还可以借助命令 diff 来进行文件的对比。
diff 文件名1 文件名2 //diff是比较命令
如下图中,a.out和b.out的内容完全一致,没有输出。而a.out和b.out的内容不一致,会输出比较结果。

千万要注意的是,代码中的文件名一定要和题目要求保持完全一致,不然就爆0了。
二、代码目录结构
在信息学奥赛第二轮提交代码时,没有像OJ一样的系统,而是让学生将代码保存在考试机器上的某个目录下。
文件保存不要放在桌面或者C盘(操作系统盘),有可能系统重启造成丢失,那样就惨了。删除文件务必谨慎,删除前多拷贝一份,以防万一。

目录操作小结:
└── HN-00001----------------------------------------------<目录>
├── task1---------------------------------------------<目录>
│ └── task1.cpp----------------------------------<文件>
├── task2---------------------------------------------<目录>
│ └── task2.cpp-------------------------------------<文件>
└── task3---------------------------------------------<目录>
└── task3.cpp----------------------------------<文件>

- 建立以准考证号命名的文件夹。(根据考场要求,比如在D盘,目录名和文件名 一定要是全英文格式,如 HN-00001)
- 文件夹内需要建立以题目命名的子文件夹,里面包含.cpp文件。输入输出均为文件,选手程序读取文件与写入文件操作均在当前路径下,不带任何绝对路径。
三、操作系统环境
信息学奥赛复赛采用的判题机是noilinux环境,要学会linux下的代码编译、运行方法,主要是为了能够在linux环境上编译、测试运行自己的C++代码,避免不必要的失误爆0。
考试环境一般有两种:
- windows系统 +(虚拟机软件vmware+noilinux环境)
- 纯noilinux环境
- 我们当然选择第一种。
Linux上使用code blocks来编写、编译运行C++源代码。命名我们的文件夹(注意:文件路径中都是英文,不要使用中文)。使用命令行编译、运行更简单:

找到linux上的“终端”软件,双击打开。

pwd //查看当前所在目录
ls //查看当前目录下的文件
cd p1 //cd是进入某个目录的命令,cd p1进入当前目录中的p1目录
g++ main.cpp //编译当前目录下的main.cpp,没有任何返回表示编译通过
g++ main.cpp -o a1 //编译main.cpp,并将编译执行文件指定名字为a1
./a1 //运行a1,可以看到运行a1输出hello world!,如果需要输入,你可以在运行后输入测试数据,然后回车会返回输出数据。
cd .. //返回上一级目录
cd ../.. //返回上两级目录
cd p1/bin/Debug //进入当前目录下的p1中的bin中的Debug目录
more main.cpp //查看main.cpp文件内容
windows和Linux相互拷贝文件内容

考场中的机器一般是开了共享粘贴板功能的,可以在windows和linux系统间拷贝文件的内容,考前注意测试一下。如果分配的考试机器不好用,开考前尽早向监考老师反馈,寻求解决。
虚拟机没有打开和windows的相互拷贝功能,我们打开上面的“设备-》共享粘贴板-》双向”。(在使用双向拷贝或者共享功能前,需要在vmware使用安装增强功能,然后再到noiLinux系统中安装vmtool,可能需要重启虚拟机linux才能生效)。每个版本的虚拟机软件菜单可能略有不同,稍微找一找就能找到。
四、比赛时的一些建议:
- 比赛时候的输入、输出建议尽量使用 scanf printf,特别是数据量比较大的情况。
- 对字符或字符串的处理可以使用:fgets、getchar、scanf、getline。
- 数组定义全局变量优先,根据题意开数组大小,可以稍微大一点。
- 小心爆int,爆long long。(注意long long格式控制符是%lld)
- 对于浮点数全都统一用double,不要用float。(注意double格式控制符是%lf)
- 不能使用的变量名,比如dfs、next、search、index、pow、min、max、y1、x0、link、map、pipe、ws、time等。