2.4 算法竞赛中的输入输出框架

版权声明:转自翠羽黄衫的博客! https://blog.csdn.net/ac1085589289/article/details/86592450

例题2-5 数据统计

输入一些整数,求出它们的最小值、最大值和平均值(保留3位小数)。输入保证这些 数都是不超过1000的整数。
样例输入:
2 8 3 5 1 7 3 6
样例输出:
1 8 4.375

程序2-9 数据统计(有bug)

#include<stdio.h> 
int main() 
{  
	int x, n = 0, min, max, s = 0;
	while(scanf("%d", &x) == 1)   
	{    
		s += x;    
		if(x < min) min = x;    
		if(x > max) max = x;    
		n++;  
	}
	printf("%d %d %.3f\n", min, max, (double)s/n);  
	return 0; 
}

提示

  1. 在Windows下,输入完毕后先按Enter键,再按Ctrl+Z键,最后再按Enter 键,即可结束输入。在Linux下,输入完毕后按Ctrl+D键即可结束输入。
  2. 把输入数据保存在文件中,输出数据也保存在文件中。这 样,只要事先把输入数据保存在文件中,就不必每次重新输入了;数据输出在文件中也避免 了“输出太多,一卷屏前面的就看不见了”这样的尴尬,运行结束后,慢慢浏览输出文件即 可。如果有标准答案文件,还可以进行文件比较,而无须编程人员逐个检查输出是否正确。
  3. 使用文件最简单的方法是使用输入输出重定向,只需在main函数的入口处加入以下两条语句:加入以下两条语句:
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);

上述语句将使得scanf从文件input.txt读入,printf写入文件output.txt。事实上,不只是scanf 和printf,所有读键盘输入、写屏幕输出的函数都将改用文件。尽管这样做很方便,并不是所 有算法竞赛都允许用程序读写文件。甚至有的竞赛允许访问文件,但不允许用freopen这样的 重定向方式读写文件。参赛之前请仔细阅读文件读写的相关规定。
4. 有一 种方法可以在本机测试时用文件重定向,但一旦提交到比赛,就自动“删除”重定向 语句。代码如下:

程序2-10 数据统计(重定向版)

#define LOCAL 
#include<stdio.h> 
#define INF 1000000000 
int main() 
{ 
	#ifdef LOCAL  
	freopen("data.in", "r", stdin);  
	freopen("data.out", "w", stdout); 
	#endif  
	int x, n = 0, min = INF, max = -INF, s = 0;  
	while(scanf("%d", &x) == 1)  
	{    
		s += x;    
		if(x < min) min = x;    
		if(x > max) max = x; 
		/*    printf("x = %d, min = %d, max = %d\n", x, min, max); */    
		n++;  
	}  
	printf("%d %d %.3f\n", min, max, (double)s/n);  
	return 0; 
}

这是一份典型的比赛代码,包含了几个特殊之处:

  1. 重定向的部分被写在了#ifdef和#endif中。其含义是:只有定义了符号LOCAL,才编译两条freopen语句。 输出中间结果的printf语句写在了注释中——它在最后版本的程序中不应该出现,但是又舍不得删除它(万一发现了新的bug,需要再次用它输出中间信息)。将其注释的好处 是:一旦需要时,把注释符去掉即可。
  2. 上面的代码在程序首部就定义了符号LOCAL,因此在本机测试时使用重定向方式读写文 件。如果比赛要求读写标准输入输出,只需在提交之前删除#defineLOCAL即可。一个更好的方法是在编译选项而不是程序里定义这个LOCAL符号,这样,提交之前不需要修改程序,进一步降低了出错的可能。

程序2-11 数据统计(fopen版)

#include<stdio.h> 
#define INF 1000000000 
int main() 
{  
	FILE *fin, *fout;  
	fin = fopen("data.in", "rb");  
	fout = fopen("data.out", "wb");  
	int x, n = 0, min = INF, max = -INF, s = 0;  
	while(fscanf(fin, "%d", &x) == 1)  
	{    
		s += x;    
		if(x < min) min = x;    
		if(x > max) max = x;    n++;  
	}  
	fprintf(fout, "%d %d %.3f\n", min, max, (double)s/n);  
	fclose(fin);
  	fclose(fout);  
	return 0; 
}

提示

  1. 先声明变量fin和fout(暂且不用考虑FILE*),把scanf改成fscanf,第一个参数为fin;把printf改成fprintf,第一个参数为fout,最后执行fclose,关闭两 个文件。
  2. 在算法竞赛中,如果不允许使用重定向方式读写数据,应使用fopen和 fscanf/fprintf进行输入输出。
  3. 如果想把fopen版的程序改成读写标准输入输出,只需赋值“fin =stdin;fout=stdout;”即可,不要调用fopen和fclose(10)。

例题2-6 数据统计II

输入一些整数,求出它们的最小值、最大值和平均值(保留3位小数)。输入保证这些 数都是不超过1000的整数。
输入包含多组数据,每组数据第一行是整数个数n,第二行是n个整数。n=0为输入结束 标记,程序应当忽略这组数据。相邻两组数据之间应输出一个空行。
样例输入:
8
2 8 3 5 1 7 3 6
4
-4 6 10 0
0
样例输出:
Case 1: 1 8 4.375
Case 2: -4 10 3.000

程序2-12 数据统计II(有bug)

#include<stdio.h> 
#define INF 1000000000 
int main() 
{  
	int x, n = 0, min = INF, max = -INF, s = 0, kase = 0;  
	while(scanf("%d", &n) == 1 && n)  
	{    
		int s = 0;    
		for(int i = 0; i < n; i++) 
		{      
			scanf("%d", &x);      
			s += x;      
			if(x < min) min = x;      
			if(x > max) max = x;    
		}    
		if(kase) printf("\n");    
		printf("Case %d: %d %d %.3f\n", ++kase, min, max, (double)s/n);  
	}  
	return 0; 
}

提示

  1. 在多数据的题目中,一个常见的错误是:在计算完一组数据后某些变量没 有重置,影响到下组数据的求解。
  2. :当嵌套的两个代码块中有同名变量时,内层的变量会屏蔽外层变量,有时 会引起十分隐蔽的错误。

猜你喜欢

转载自blog.csdn.net/ac1085589289/article/details/86592450