这里写的是"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
但问题是如何枚举的更快一些?
“跳着枚举”,在第一次找到体力的高峰期和下一次体力的高峰期
之间会有很多不需要判断的日子,所以我们可以每次加23天,省去中间的日子,同理,在第一次找到体力和情商高峰期同时出现的一天之后,就可以跳过中间23和28的最小公倍数天,直到找到三个高峰同时出现的一天。
1.3称硬币
现在有11枚真币和1枚假币,不知道假币是重是轻,现有一个天平,给出三次测量结果,试给出哪一枚硬币是假币,是重还是轻,题目保证能得出结果。
解题思路:
用枚举的方法,我们分别假设第一到第十二枚硬币为假币,是重或者轻,然后再代入给出的结果进行检验,如果三次检验后的结果都通过就说明找到了假币,思路还是比较容易的。
补充:
找出假币有更普遍的规律,即讨论最少称几次能从n枚硬币中找到假币,见洛谷P1431 找出伪币。
1.4熄灯问题
原题描述复杂,见POJ1222
解题思路:
拿到题第一思路应该就是枚举,一共有5x6个开关,每个开关对应0和1,如果是直接来的话,就有种方式,太多了会超时。我们就需要思考如何减少枚举的数目。
基本思路:找到某个“局部”,当局部的状态确立之后,局部以外的状态只能是确定的一种或者不多的n种,这样就减少了枚举的总数,只需要枚举这局部的状态就可以。
对于本题来说,存在着这样的“局部”----第一行的开关状态,假设第一行的开关状态被确立之后,是不是第二行就紧跟着被确立了?因为我们想要达到30个开关全部关闭的状态,那么第一行开着的灯只能由第二行关闭,所以第一行的开关状态就是我们需要的“局部”,我们只需要枚举第一行的全部状态,检查最后是否全部关闭即可。
二、递归
提到递归,我们就应该思考两点,递归终点和递归表达式,尽可能的找到题目要求的f(n)和f(n-1)甚至与f(n-2)的关系。
2.2汉罗塔Hanoi
提到递归就有著名的汉罗塔问题,这里简述一下问题,有个从大到小的圆盘摆
放在
柱上(大在下),要把这
个圆盘放在
柱上,中途可以借用
柱,要求不得出现大盘在小盘上面。
解题思路:
我们要有整体和局部的思想,也要考虑极端情况下。
题目说了有个圆盘在
柱上,我们先思考
的时候,只需要直接把这个圆盘从
就可以了
再来考虑的情况,这时候就要想到整体和局部,要把这
个圆盘移动到
柱上可以简化成以下3个步骤
1、把最上面个圆盘移动到
柱。
2、再把剩下第个圆盘移动到
柱上。
3、最后把柱上的圆盘移动到
柱上。
但是我们需要考虑的是能否把这n-1个圆盘看成整体来移动?
答案是能的,考虑递归函数,在处理这个圆盘的时候,再把第n-1个圆盘单独出来,把上面
个圆盘看成整体