- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
搜索练习题题解report_search
THE REPORT OF SEARCH
Divisors
本题的意思是,给你一段区间,求其中含因子个数最多的整数。(包括端点)
我们知道,任何一个整数N都可以写成:N a1^p1 * a2^p2 * a3^p3 * … * am^pm的形式,其中p[1~m]是N的m个质因子,那么N的因子个数为: p1 + 1 * p2 + 1 * p3 + 1 * … * pm + 1 。
最容易想到的算法是:枚举区间中的每个整数,再计算出它有多少个因子,其算法复杂度为O u – l * sqrt k ,按题目中给的数据范围,高达O 109 * 109 / 2 ,无法承受。 l、u为上下界,k为区间中的每个数
比较两个数n和n*p,其中p为质数,我们在枚举的时候会计算两次n的因子数,这是显然没有必要的。所以我们找到了一种新的搜索顺序——枚举质因子。
算法思想大致为:设当前搜索到的数为now,初始值为1,然后now now * pk,其中p取2、3、5……k取0、1、2、3……当now low时,说明now已经属于该区间,就用now去更新max,终止条件为:now u。
单单这样是不够的,因为复杂度还是有O 109 ,所以我们还需要进行适当的剪枝。
可行性剪枝:当[ l - 1 / now] [ u – 1 / now]时,表示下一步扩展的数一定不在区间内,故可以剪去。
最优性剪枝:如果当前搜索状态为 k, s, now ,其中now为当前搜索到的数,k为当前枚举的质因子,s为now的因子数。那么剩下的因子数最多为q logk u / now ,这些因子组成的最大个数为2q,如果s * 2q max,说明这个数无论如何扩展都不会优于max,故可以剪去。
至此,问题得到解决。需要注意的是,一般搜索都需要加剪枝,而最基本的就是可行性和最优性剪枝,对于不同问题两个剪枝的效果不同,就本题而言,显然最优性剪枝的作用大得多。
Game
题目要求的是最短着棋序列,显然用BFS,关键是如何判重。
注意到棋盘中每一点只可能是0或1(白棋或黑棋),且整个棋盘只有16个点,所以我们想到可以将每一状态对应一个16位的二进制数。不妨设一个判重数组p[1~216 – 1],初始值为false,当扩展出一种状态,我们求出将该状态对应的二进制数i,将p[i] : true,表示该状态已经存在。
另外,我们再考虑如何交换相邻的两个格子。我的算法是直接将上下左右对应成:当前位置 i -4, +4, -1, +1 ,其中特殊判断左右边界。(这个其实很慢,但数据弱阿!)
资料上介绍的算法是位运算。
经归纳总结,左右相邻公式为:sk s xor 3 * 215 - k ,其中k 4, 8, 12, 16;上下相邻公式为:sk s xor 17 * 212 - k ,其中k 12。
因为比较容易,这里不再赘述,大家可以自行推导。值得注意的是,这里交换的两个棋子的颜色必须不同,否则公式不成立。
Puzzle
Magic
此题就是解方程,由于矩阵中元素范围为1~16,将一些变量通过循环枚举,其余的能推则推就OK了。
Panel
因为操作的方式只有两种,即:
1 任选一行,改变该行中所有灯泡的状态,即亮的变暗、暗的变亮; 2 任选两列,交换其位置。
所以,我们不妨先枚举第一列是哪一列,然后再根据对应的目标状态确定每一行是变还是不变。最后看是否存在一种方案——将第2~m列重新组装——使得它与目标状态完全一致即可。
总的来说,这道题目的关键就在于:确定了第一列以后就可以跟着确定每一行要不要变,因此矩阵中的元素就都确定好了,我们只需要在列于列之间进行组装即可。
分析程序的复杂度,为O(数据组数 * m2 * n),上限为(k * 106)。其中k不超过5,完全可以接受。
Scan
我们首先来明确一下部件的概念,题目是这样描述的:
1 如果一个像素属于某部件,则或者该像素至少与该部件的一个像素相邻,或者该像素单独组成一个部件。 说明:每一个像素与前后、左右、上下的6个像素相邻 2 同一个部件内部,相邻两个像素的灰度差不超过正整数M。M决定了程序识别部件
的灵敏度。
意思就是,只要这个部件中任意两个相邻的像素灰度差不超过M就OK了。换言之,如果两个像素灰度差巨大,但他们不相邻,这是合法的。所以其实这也就引进了一个新问题:若是将题目条件换成“同一个部件中任何两个像素灰度差不能超过M”怎么做?大家可以自己思考并加以解决。: P
明确了这个概念以后,我们来看如何解决问题。
因为只要保证相邻的像素满足条件,所以我们猜想,是不是可以任意选一个当前未染色的点A(即该点还不属于任何部件)进行扩展,直到不能扩展为止,而
文档评论(0)