ACM题目中输入数据的处理(C语言版)

 ACM竞赛题目的输入数据常要求有多组,并且格式多种多样,这是初次登OJ平台的同学的一个障碍。实际上,这些格式可以归为固定的几种类型,本文介绍各种类型的处理方法,以帮助同学们克服这些障碍。  实际上,这些模式不仅是OJ平台上做题的需要。在平时的自由编程练习中,也可以自行使用这些模式,以提高调试程序的效率。对程序测试的意识也将在此过程中得到提升。
  本文1-4部分介绍了几种类型输入的处理,第5部分介绍通过输入重定向提高调试程序效率的方法。

  1. 最简单的输入
    例1:

    [plain] view plaincopyprint?
    1.Description
    2.计算 a+b


    1. 4.Input
      5.两个整数 a,b

    2. 7.Output
      8.a+b的值

    3. 11.Sample Input
      12.1 2

    4. 14.Sample Output
      15.3

Description计算 a+bInput两个整数 a,bOutputa+b的值Sample Input1 2Sample Output3  这种最简单的输入,接受一组输入,针对这组输入计算出值即可。这与平时的程序设计并无差异。解决办法是:

[cpp] view plaincopyprint?

      #include <stdio.h>  
      int main()  
      {  
          int a,b;  
          scanf("%d %d",&a, &b);  
          printf("%d\n",a+b);  //对其他题目,换成要求的复杂处理与输出  
          return 0;  
      }  
    #include <stdio.h>
    int main()
      { 
          int a,b; 
          scanf("%d %d",&a, &b); 
          printf("%d\n",a+b);
      }

//对其他题目,换成要求的复杂处理与输出 return 0;}

  1. 一次运行,要输入多组数据,直到读至输入文件末尾(EOF)为止
    例2:

[plain] view plaincopyprint?
1.Description
2.计算 a + b
3.
4.Input
5.多组由两个整数(a和b)构成的输入,a和b之间用空格隔开,每组输入单独占一行
6.
7.Output
8.每组的两个整数(a和b)求和并输出,每组的求和结果独占一行
9.
10.Sample Input
11.1 5
12.10 20
13.400 516
14.
15.Sample Output
16.6
17.30
18.916
Description计算 a + bInput多组由两个整数(a和b)构成的输入,a和b之间用空格隔开,每组输入单独占一行 Output每组的两个整数(a和b)求和并输出,每组的求和结果独占一行Sample Input1 510 20400 516Sample Output630916  这种输入包含多对输入数据,需要构造一个循环读取。因为没有指出到底有多少对输入,要有办法判断输入何时结束。解决办法是:

[cpp] view plaincopyprint?

1.#include <stdio.h>  
2.int main()   
3.{  
4.    int a,b;  
5.    while(scanf("%d %d",&a, &b) != EOF) // 输入结束时,scanf函数返回值为EOF(-1),即没有数据输入时会退出while循环  
6.    {  
7.        printf("%d\n",a+b);  
8.    }  
9.    return 0;   
10.}  

include <stdio.h>int main() { int a,b; while(scanf("%d %d",&a, &b) != EOF) // 输入结束时,scanf函数返回值为EOF(-1),即没有数据输入时会退出while循环 { printf("%d\n",a+b); } return 0; }  说明:scanf函数返回值就是读出的变量个数,如果一个都没有,则返回值是-1。EOF是一个预定义的常量,等于-1。

  1. 一次运行,要输入多组数据,组数由第一个输入数据决定(在开始的时候输入一个N,接下来是N组数据)
    例3:

[plain] view plaincopyprint?
1.Description
2.计算 a + b
3.
4.Input
5.第一行是数据的组数N,从第二行是N组由两个整数(a和b)构成的输入,a和b之间用空格隔开,每组输入单独占一行
6.
7.Output
8.每组的两个整数(a和b)求和并输出,每组的求和结果独占一行
9.
10.Sample Input
11.2
12.1 5
13.10 20
14.
15.Sample Output
16.6
17.30
Description计算 a + bInput第一行是数据的组数N,从第二行是N组由两个整数(a和b)构成的输入,a和b之间用空格隔开,每组输入单独占一行 Output每组的两个整数(a和b)求和并输出,每组的求和结果独占一行Sample Input21 510 20Sample Output630  需要先读入第一行确定组数N,而后写一次执行N次的循环进行处理即可。解决办法是:

[cpp] view plaincopyprint?

1.#include<stdio.h>  
2.int main()  
3.{  
4.    int n,i;  
5.    int a,b;  
6.    scanf("%d",&n);  
7.    for(i=0;i<n;i++)  
8.    {  
9.        scanf("%d%d",&a,&b);  
10.        printf("%d\n",a+b);  
11.    }  
12.    return 0;  
13.}  

include<stdio.h>int main(){ int n,i; int a,b; scanf("%d",&n); for(i=0;i<n;i++) { scanf("%d%d",&a,&b); printf("%d\n",a+b); } return 0;}

  1. 输入不说明有多少组数据,但以某个特殊输入为结束标志。平时做题中常见诸如“输入学生成绩,以-1结束”,没有学生得-1分的,这个结束数据可以要得。
    例4:

[plain] view plaincopyprint?
1.Description
2.计算 a + b
3.
4.Input
5.多组由两个整数(a和b)构成的输入,a和b之间用空格隔开,每组输入单独占一行。当输入为 0 0 时,输入结束。
6.
7.Output
8.每组的两个整数(a和b)求和并输出,每组的求和结果独占一行。
9.
10.Sample Input
11.1 5
12.10 20
13.0 0
14.
15.Sample Output
16.6
17.30
Description计算 a + bInput多组由两个整数(a和b)构成的输入,a和b之间用空格隔开,每组输入单独占一行。当输入为 0 0 时,输入结束。Output每组的两个整数(a和b)求和并输出,每组的求和结果独占一行。Sample Input1 510 200 0Sample Output630  构造循环对数据进行处理,将是否遇到了要求结束的输入,作为循环是否结束的依据。解决办法是:

[cpp] view plaincopyprint?

1.#include <stdio.h>  
2.int main()  
3.{  
4.    int a,b;  
5.    while(scanf("%d %d",&a, &b) &&(a||b))  
6.    {  
7.        printf("%d\n",a+b);  
8.    }  
9.    return 0;  
10.}  

include <stdio.h>int main(){ int a,b; while(scanf("%d %d",&a, &b) &&(a||b)) { printf("%d\n",a+b); } return 0;}

  有关字符和字符串数据的输入,在此不再多讲,只要将相关的函数用好即可,也可以找到相关资料参考。

  1. 利用文件重定向提高调试效率
      编程得到正确结果前,往往需要多次运行程序,每次运行都需要花费不少的时间从键盘输入数据。每次输入的数据都是相同的时,会给人的心理带来不爽的感觉,并造成时间上的浪费。无论平时练习还是ACM竞赛实战,这些都是可以避免的。方法是,运用重定向。
      用下面的形式调用函数freopen()会将标准输入stdin重定向到文件input.txt(这个名字可以自己定义)。

[cpp] view plaincopyprint?
1.freopen("input.txt","r",stdin); //设置输入和输出文件
freopen("input.txt","r",stdin); //设置输入和输出文件  重定向后,原先从键盘(标准输入的默认设备)接受的输入,将统统从文件读取input.txt读取,这就是重定向。程序可以写作:

[cpp] view plaincopyprint?

1.#include<stdio.h>  
2.int main()  
3.{  
4.    freopen("input.txt","r",stdin);  //只加这一句输入将被重定向到文件input.txt  
5.    int a,b;  
6.    scanf("%d%d",&a,&b);  
7.    printf("%d\n",a+b);  
8.    return 0;  
9.}  

include<stdio.h>int main(){ freopen("input.txt","r",stdin); //只加这一句输入将被重定向到文件input.txt int a,b; scanf("%d%d",&a,&b); printf("%d\n",a+b); return 0;}  于是,在运行程序前,将本该由键盘输入的数据,写到文件input.txt中。而在运行程序时,数据将不再需要人去输入。那个快,很享受。

  需要注意的是,调试通过的程序,千万不要直接提交到OJ平台上去。如果竞赛中这样做了,罚你的20分钟不要算到我的头上。提交的程序要把输入重定向的一行删除,这样才算是符合要求的,可以获得AC的程序。

  除了删除那一行,还有一种简单的做法是,提交前将这一行前加上注释符"//",效果是一样的。

[cpp] view plaincopyprint?

1.#include<stdio.h>  
2.int main()  
3.{  
4.    //freopen("input.txt","r",stdin);  //只加这一句输入将被重定向到文件input.txt  
5.    int a,b;  
6.    scanf("%d%d",&a,&b);  
7.    printf("%d\n",a+b);  
8.    return 0;  
9.}  

include<stdio.h>int main(){ //freopen("input.txt","r",stdin); //只加这一句输入将被重定向到文件input.txt int a,b; scanf("%d%d",&a,&b); printf("%d\n",a+b); return 0;}


B0B0
268 声望7 粉丝

过顺其自然的生活,做随遇而安的自己。