【紫书总结】第二章 --- 循环结构程序设计

优秀代码

判断n是否为完全平方数

floor(double) 函数的运用

#include<stdio.h>
#include<math.h>

#define _rep(i, a, b) for (int i = (a); i <= (b); ++i)

int main()
{
	_rep(a, 1, 9) _rep(b, 0, 9)
	{
		int n = a * 1100 + b * 11; // 先制造一个数
		// 如果一个数是平方数的话,那么他开平方后再平方的结果是一样的
		// 所以使用开平方函数sqrt, 但是会有精度丢失的问题,那么就将其 + 0.5
		// 再对其进行 向下取整 (使用函数floor)
		// 机器在经过大量运算之后由于误差, 1 有可能会变成0.9999999999造成使用floor时得到的值是0,而不是1,所以加一个0.5之后就避免了这样的误差
		// 进行判断平方后是否是原来的数值
		int m = floor(sqrt(n) + 0.5); 
		if (m * m == n) printf("%d\n", n);
	}
	return 0;
}

判断运行时间

printf("Time used = %.2f\n", (double)clock() / CLOCKS_PER_SEC);


输入太麻烦, 不想每次都输入同一组数据

文件重定向


#define LOCAL // 宏定义 提交时直接注释即可

int main()
{
#ifdef LOCAL
	freopen("data.in", "r", stdin); // 文件读取操作
	freopen("data.out", "w", stdout);//文件写入操作
#endif


 // 假装有代码
	
}

VS用户不想总是宏定义,提交时还要注释掉宏定义,太麻烦了
vincent
在这里插入图片描述
在这里插入图片描述
问题解决,本地直接提交即可,不用注释了, 在我们的编译器中,一直帮我们定义了, 所以会使用文件重定向,而oj平台上没有定义这个,不会执行文件重定向。

比赛要求用文件输入输出, 但禁用文件重定向。
使用文件读取操作
fopen版本

int main()
{
	FILE* fin, * fout;
	fin = fopen("data.in", "rb"); // 二进制文件读取
	fout = fopen("data.out", "wb"); // 二进制文件写入

	int a;
	while (fscanf(fin, "%d", &a) == 1) fprintf(fout, "%d\n", a);
 	
	// 不要忘记关闭文件
	fclose(fin);
	fclose(fout);
	return 0;
}

这个也很方便,因为我们写算法的时候不需要用到太多的输入输出, 只需要在提交的时候把代码改改就行了。


疑难问题解决

例题2-4为什么 n >= 25 答案唯一?

因为25!尾数有六个零,25~29的阶层都是6个零,30!有7个零……也就是说n>=25时,结果唯一。
怎么知道25!尾数有6个零呢?
我们知道, 尾部零是有2和5相乘而得,2在这其中出现的次数是比较多的, 所以我们只需要找5有多少个就行了, 6个5,那么便是6个零了。


编码小技巧

  1. 当遇到比较复杂的题目的时候,伪代码的作用十分重要, 能够把你的代码思路和时间复杂度展现出来,方便修改成更好的代码。
  2. 样例对了,程序不一定对了,所以我们要深刻理解题意, 每次去用那种极端条件进行测试。
  3. 最简单的输出方法就是使用printf“输出中间结果”,看看与自己想象中的答案有哪些不同。
  4. 在算法竞赛中, 有经验的选手往往会使用条件编译指令(#ifdef #endif)并且将重要的测试语句注释而非删除。
  5. 当嵌套的两个代码块中有同名变量时,内层的变量会屏蔽外层变量,有时会引起十分隐蔽的错误。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值