前言
刚接触牛客的OJ(Online Judge)编程,吃了不少亏,故写下此小短文。
OJ判分原理
牛客的oj判分系统采用的是标准文件输入/输出,也就是说你先编程读取键盘的输入(这里oj系统会把输入文件映射到键盘输入区用以模拟键盘输入),接着你要编程按照一定的输出格式将结果输出到屏幕终端(与输入类似,oj系统会把你编程输出到屏幕终端的内容写入到一个文件中),最后通过对比你写的文件和oj系统预先存入文件的结果,看你的答案与预先输入的答案有多少是一致的,比如完全相同,则表示你成功通过了所有测试,即ac100%。
关于while(cint>>x)
既然oj会用输入文件模拟键盘输入,那我们在编程的时候就要考虑如何去接收这些数据并做处理。下面一个具体例子做说明:
链接:https://ac.nowcoder.com/acm/contest/5652/F
来源:牛客网
题目描述
计算一系列数的和
输入描述:
输入数据有多组, 每行表示一组输入数据。
每行的第一个整数为整数的个数n(1 <= n <= 100)。
接下来n个正整数, 即需要求和的每个正整数。
输出描述:
每组数据输出求和的结果
示例1
4 1 2 3 4
5 1 2 3 4 5
输出
10
15
c++实现
//输入文件为
/*
4 1 2 3 4
5 1 2 3 4 5
*/
//eof标识符会自动加到文件末尾
#include<iostream>
using namespace std;
int main(){
int t;
while(cin>>t){
int num,sum=0;
for(int i=1;i<=t;++i){
cin>>num;
sum+=num;
}
cout<<sum<<endl;
}
return 0;
}
好奇的同学读到这里应该就会有疑惑,while(cin>>t)是怎么跳出循环的?核心其实在于文件的末尾都会包含一个EOF标识符,而cin其实是一个特殊的类对象,执行cin>>t,其实就是执行cin.operator>>()并返回cin类对象本身,当读入的值为EOF时,读入操作会将cin对象里的eofbit状态位设为1,表示读到了文件尾,我们可以通过cin.eof()来获取eofbit状态位的状态值,即可以检测是否读到了文件尾。同样地,while循环将整个cin对象读入后,当然也就能够获得eofbit的状态,从而确定是否跳出循环了。
此外,当cin读入的对象为EOF时,会将最后一次非EOF的值写入目标变量中,并且在遇到EOF后也能继续执行cin>>t,只不过现在的t会是最后一次非EOF的值,并且eofbit状态位始终为1。测试代码见下:
//测试当遇到EOF,还执行cin>>t操作会怎么样
//输入文件为
/*
4 1 2 3 4
5 1 2 3 4 5
*/
//eof标识符会自动加到文件末尾
#include<iostream>
using namespace std;
int main(){
int t;
while(1){
//用isEof保存执行 cin>>t 后的eofbit位的状态,并打印一下
bool isEof = (cin>>t).eof();
cout<<"eofbit:"<<isEof <<" t:"<<t<<endl;;
//若isEof 为真,则表示读到了文件尾
if(isEof ==true) {
//下面这段代码的目的是看一下当读到文件尾后
//是否能继续读入,实验证明是可以的!
for(int i=1;i<=5;i++){
cin>>t;
cout<<"end"<<cin.eof()<<" t:"<<t<<endl;
}
break;
}
int num,sum=0;
for(int i=1;i<=t;++i){
cin>>num;
sum+=num;
}
// cout<<sum<<endl;//为了更好的观察测试,这里将这个输出屏蔽
}
return 0;
}
输出结果如下:
eofbit:0 t:4
eofbit:0 t:5
eofbit:1 t:5
end1 t:5
end1 t:5
end1 t:5
end1 t:5
end1 t:5