计算机程序设计实训记录(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我基本全忘了,还是等我复习复习一下吧,呜呜呜。

浙公网安备 33010602011771号