第一篇文章以此开始也不错的说。
本学期系里开了算法课,老师是院里的ACM教练,所以同学们不管有无比赛的打算都不得不在OJ上做题了。
而很多人跨不过第一步,就是困在了OJ系统严格的输入输出控制上,比如 HOJ1089.
因为是初学内容,所以以下代码都用C语言哦~
如果你看不懂 a series of pairs of integers a and b 想说明什么,那就会写成这样:
#include <stdio.h>
int main()
{
int a,b;
scanf("%d%d",&a,&b);
printf("%d",a + b);
return 0;
}
结果是Wrong Answer.即答案错误,因为题目要求你读入一个文件的数据并做计算,而你只读了第一组,程序就结束了。
看到 a series,multiple test cases这种关键字,就要反应过来这是要执行读到文件结尾的操作。
下面是能够实现读到文件结尾的代码:
#include <stdio.h>
int main()
{
int a,b;
while(scanf("%d%d",&a,&b)!=EOF)
printf("%d",a + b);
return 0;
}
提交后我们会看到结果变成了Presentation Error.即格式错误,因为题目要求输出数据每个结果占一行,你会发现%d后面是没有换行的,那么你的输出数据都将挤在了一行里。
这里有人要说,我在控制台里看两个结果并不在一行啊?那是因为你在敲入数据时打了回车,试想如果程序的输出都直接写入文件,那结果一定都是连在一起的(回头还会再说这个问题)。所以题目要求哪里换行就换行,要求哪里空格就空格。可以说PE是最轻的错误吧,因为离成功只有一步之遥了!
于是,在适当的地方加上换行符,提交代码:
#include <stdio.h>
int main()
{
int a,b;
while(scanf("%d%d",&a,&b)!=EOF)
printf("%d\n",a + b);
return 0;
}
提交的结果是Accepted,意味着你的代码通过了OJ的数据测试。虽然程序不一定完全正确,但在这种评判方式下,此结果意味着你的程序可以得分啦O(∩_∩)O
AC的喜悦过后,可以简单探讨一下,为什么这样可以读到文件结尾?
这要涉及到scanf函数的返回值。其实scanf函数也是有返回值的,返回值为成功读入的数据个数,比如上面的程序,正常读入的话就返回2. 但是在读到文件结尾时,它会返回一个特殊的值 -1, 因为这个特性,C语言专门设了一个宏定义 EOF ,end of file的意思,它的值就是-1.那返回值不等于EOF意思不就是没有读到文件结尾吗?
类似的有人把while括号里写成 ~scanf("%d%d",&a,&b) ,这里 ~ 的意思是按位取反,至于为什么可以这么写,不妨结合补码的知识思考一下~~~
至此把第一种(也是跟平时编程最不同的一种)输入处理介绍完了,下面可以快速的介绍一下其它几种经常在题目中出现的输入要求及其解决办法(其实这些都很好想到,不看也能自己搞定的):
1、给定测试数据的组数,如HDU1090:
方法很简单,用一个变量 t 控制循环次数即可。
#include<stdio.h>
int main()
{
int a,b,t;
scanf("%d",&t);
while(t--){
scanf("%d%d",&a,&b);
printf("%d\n",a + b);
}
return 0;
}
2、输入两个 0 时结束程序(将来根据条件可以是若干个0,稍作改动即可),如 HDU1091:
#include<stdio.h>
int main()
{
int a,b;
while(1){
scanf("%d%d",&a,&b);
if(a==0 && b==0) break;
printf("%d\n",a + b);
}
return 0;
}
以上三种情况,大致可以囊括OJ程序的基本数据输入要求了。当然将来还会遇到各种神奇的输入,处理起来也不方便,不过那是后话了,前期题目靠这三种方法是完全可以完成任务的。
另外 HDU1092 HDU1093 HDU1094 HDU1095 HDU1096 都是 A+B 的题目,但涉及更精细的输入控制,多说无益,自己开动脑筋搞定它们吧~
在CSDN的第一篇文章,就是以上。
今后昊昊还会继续加油学习的~