程序设计与算法

这里写的是"MOOC程序设计与算法"----郭灿的笔记

一、枚举

1.2生理周期

人有体力,情商,智商的高峰期,分别每隔23天,28天,33天出现一次,我们想知道每个人何时三个高峰落在同一天。
给定三个高峰出现的日子abc,给定任意一天d,输出距离下一次三个高峰落在同一天还有多久。

保证输出天数小于21252。

解题思路:

对于d+1~21252之间的每一天k,只需要判断是否同时是体力情商智商的高峰期即可,即判断k和abc的差是否同时分别为23,28,33的整数倍,即判断下式是否为真:

(k-a)%23==0&&(k-b)%28==0&&(k-c)%33==0

但问题是如何枚举的更快一些?

“跳着枚举”,在第一次找到体力的高峰期k_1和下一次体力的高峰期k_2之间会有很多不需要判断的日子,所以我们可以每次加23天,省去中间的日子,同理,在第一次找到体力和情商高峰期同时出现的一天之后,就可以跳过中间23和28的最小公倍数天,直到找到三个高峰同时出现的一天。

1.3称硬币

现在有11枚真币和1枚假币,不知道假币是重是轻,现有一个天平,给出三次测量结果,试给出哪一枚硬币是假币,是重还是轻,题目保证能得出结果。

解题思路:

用枚举的方法,我们分别假设第一到第十二枚硬币为假币,是重或者轻,然后再代入给出的结果进行检验,如果三次检验后的结果都通过就说明找到了假币,思路还是比较容易的。

补充:

找出假币有更普遍的规律,即讨论最少称几次能从n枚硬币中找到假币,见洛谷P1431 找出伪币。

1.4熄灯问题

原题描述复杂,见POJ1222

解题思路:

拿到题第一思路应该就是枚举,一共有5x6个开关,每个开关对应0和1,如果是直接来的话,就有2^{30}种方式,太多了会超时。我们就需要思考如何减少枚举的数目。

基本思路:找到某个“局部”,当局部的状态确立之后,局部以外的状态只能是确定的一种或者不多的n种,这样就减少了枚举的总数,只需要枚举这局部的状态就可以。

对于本题来说,存在着这样的“局部”----第一行的开关状态,假设第一行的开关状态被确立之后,是不是第二行就紧跟着被确立了?因为我们想要达到30个开关全部关闭的状态,那么第一行开着的灯只能由第二行关闭,所以第一行的开关状态就是我们需要的“局部”,我们只需要枚举第一行的全部状态,检查最后是否全部关闭即可。

二、递归

提到递归,我们就应该思考两点,递归终点和递归表达式,尽可能的找到题目要求的f(n)和f(n-1)甚至与f(n-2)的关系。

2.2汉罗塔Hanoi

提到递归就有著名的汉罗塔问题,这里简述一下问题,有n个从大到小的圆盘摆n-1放在A柱上(大在下),要把这n个圆盘放在C柱上,中途可以借用B柱,要求不得出现大盘在小盘上面。

解题思路:

我们要有整体和局部的思想,也要考虑极端情况下。

题目说了有n个圆盘在A柱上,我们先思考n=1的时候,只需要直接把这个圆盘从A\rightarrow C就可以了

再来考虑n> 1的情况,这时候就要想到整体和局部,要把这n个圆盘移动到C柱上可以简化成以下3个步骤

1、把最上面n-1个圆盘移动到B柱。

2、再把剩下第n个圆盘移动到C柱上。

3、最后把B柱上的圆盘移动到C柱上。

但是我们需要考虑的是能否把这n-1个圆盘看成整体来移动?

答案是能的,考虑递归函数,在处理这n-1个圆盘的时候,再把第n-1个圆盘单独出来,把上面n-2个圆盘看成整体

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

RefrainC.C.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值