计算机程序设计实训记录(1)

我是纯小白,随便写写记录一下。

目录

课程任务

在线自动判题原理

例题


课程任务

  • 在线自动判题系统练习、测验(程序设计竞赛)
  • 3种基本排序算法实验分析
  • C-字符串处理
  • 撰写小论文

呜哇,事情好多啊(bu)

在线自动判题原理

采用“黑盒测试”方法判定解题源程序代码的正确性

  • 所谓“黑盒测试”即不检查中间过程(亦即不检查程序源代码), 仅根据输入数据和输出数据判断程序的正确性
  • 因此,测试数据集的输出数据是保密的

 测试数据集(输入数据集)

  • 精心设计。多样化,尽量覆盖更多情形。(指ex的边界情况和极端情况)

 标准程序

  • 命题者提供的解题程序为“标准程序”
  • 标准程序对测试数据集的运行时间、所需的内存空间,是题干中确定时间限制、空间限制的重要依据(一般会适当放大若干倍)

 标准结果(标准答案集)

  • 标准程序对测试数据集的输出
  • 判断被测程序正确性的依据

对于一道题目

  • 已经完成了“标准程序”;
  • 已经设计了大量的测试数据(包括特殊、边界等情况)
  • 由“标准程序”和测试数据,产生了“标准答案”

对于用户的解题程序(源代码)

  • 重新编译链接生成可执行程序,然后自动运行该可执行程序,并输入测试数据。可能出现错误
  • 编译错(如缺少包含头文件)、运行时错(内存使用错误等)
  • 超时(存在永真循环,或者算法的时间复杂度过高)

结果错误(用户程序对测试数据所产生的答案,与“标准答案”不一致)

  • 出现错误时,该用户的“用时”将增加(称为“罚时”)
  • 各用户名次按正确解题数排序;解题数相同时,用时少者名次靠前。

例题

例题1 阶乘尾部0的个数

问题描述

   给定一个正整数n,计算n!的尾部0的个数。

输入

   输入数据有若干行。每行上有一个正整数n,对应一种情形。

输出

对于每一种情形,输出结果,换行。

输入样例

8

16

30

输出样例

1

3

        7

在说题目之前,有一个问题要注意,就是

输入

   输入数据有若干行。每行上有一个正整数n,对应一种情形。

如何方便地处理输入问题,对于小白而言也是一个要点。

碰到这种题,作为小白的我肯定首先想到暴力算暴力除,然鹅我们都知道,阶乘,真的很可怕,如果数值大了的话就会瞬 间 爆 炸。

所以说,暴力法,凋零。这里就只能想更为取巧的方法。

将n!进行质因数分解,我们不难发现

n!=a(2^k)*(5^m),2*5=10,且由观察可知2总是比5多的,所以说阶乘尾部0的个数,实际上由5的幂次数决定的,

再可知,5的倍数可“提供”1个0,25的倍数可以“提供”2个0,5^3的倍数可以提供3个0.

所以,只要知道n中含有几倍的5,25,125,etc,就可以得出尾部0的个数。

算法如下

 

每一个5的倍数本身提供一次0,5^2的倍数额外提供一次,故多计算一轮,5^3的倍数额外提供两次,故多计算二轮,以此类推。

由此,就可以得到我们的代码

#include <stdio.h>

int zeros(int n)
{
	int m=0, p=5;
	while(p<=n)
	{
		m += n/p;
		p *= 5;		// p的变化规律为5的1,2,3,…次方
	}
	return m;
}

unsigned long long fact(unsigned long long n)
{
	unsigned long long f=1, i;
	for(i=2; i<=n; i++)
	{
		f *= i;
		printf("%llu! = %llu\n", i, f);
	}
	return f;
}

int main()
{
//	fact(22);return 0;					// 用于测试fact何时溢出
	int n;
	while(scanf("%d", &n)==1)			// scanf函数的返回值是其读取到的数据个数
		printf("%d\n", zeros(n));	
	return 0;
}

我们就解决了这个问题,好耶!

可以注意到,这里使用了

while(scanf("%d", &n)==1)

 来解决数据输入的问题,在接下来的几道题中我们还会使用这种方法

例题2 判断算式的正确性

问题描述

给定一个算式,该算式中只含一个四则运算符号,操作数及结果均为整数。要求判断该算式的正确性(规定:除法必须除尽才可能正确)

输入

输入数据有若干行。每行上有一个算式,对应一种情形

输出

对于每一种情形,直接输出T(表示正确)F(表示错误),换行。

输入样例

1 + 2 = -3

5 / 2 = 2

4 / 2 = 2

输出样例

F

F

       T

这个问题好像就比较简单了,利用前面的技巧接收输入数据,再用分情况判断是否成立后输出就好了。

但在做题过程中,我们得注意输入的极端条件——除以0的情况,所以说,就得加入一个判断语句,遇到除以0的情况直接判错。

// OJ02.c 判断算式的正确性
#include <stdio.h>

int main()
{
	int x, y , z;
	char op, eq;
	
	while(scanf("%d %c %d %c %d", &x, &op, &y, &eq, &z)==5)
	{					// 直接接收5个输入的数据,数据类型不尽相同
		if(    (op=='+' && x+y==z)
			|| (op=='-' && x-y==z)
			|| (op=='*' && x*y==z)
			|| (y!=0 && x%y==0 && x/y==z) )
			printf("T\n");
		else
			printf("F\n");
	}
	return 0;
}

这道题也就完成了,好耶!

至于例题3,去年秋天学的C我基本全忘了,还是等我复习复习一下吧,呜呜呜。

 

 

posted @ 2020-08-01 23:28  DoRCL  阅读(298)  评论(0)    收藏  举报