本周看了十余道搜索题和一些关于搜索的资料,尤其是对于一题多解有很深的体会。在接触了一些新知识的同时,提升了对旧知识的利用能力。因为本周更多是对题解的学习和思考,AC的题目并不多,只是在学习中有了更清晰的思路和自己的想法,因此本篇博客不侧重于代码,更多是对不同题目自己的思路说明。
目录
一.题目主旨与个人思路
1.
[USACO2.1]健康的荷斯坦奶牛 Healthy Holsteins - 洛谷 |
这是一道很明显的DFS题目,和本周两场比赛中的题目大同小异,都是通过判断输入的信息内,用哪种最小的组合可以达到要求。自己在没看题解时想了一个很复杂的关于如何遍历全部情况再最后输出,但看了题解大佬们各种简单的思路后,更改了自己的思路,主要是优化了剪枝的方法和储存判断的手段。主要思路很正常,都是不断搜索各种方法累加“维生素”的值,判断所需“食物”最少的方法。具体细节确实很熬人,不过我也在这里发现了自己在搜索上一个漏洞,具体就放在比赛总结中讲吧。
2.
我看的第二大类是关于连通块的一类问题,这一类主要是要判断一个矩阵内各个元素的联系。具体问题有:
求细胞数量 - 洛谷 |
海战 - 洛谷 |
[USACO10OCT]Lake Counting S - 洛谷 |
其实,在类似的矩阵中无所谓各个元素是数字还是字符,重点其实是是否对元素标记,以及对周边元素按照题目要求判断是否在标记时,令累加器sum++。像判断字符或数字是否为要求数据的相关代码段反而简单。这道题我的第一想法其实是可以不用DFS,直接利用几个for循环和if判断解决的,不过自己在思考的时候反而用起了DFS,导致自己最后的思路很乱,但在看过题解后,两种思路就都很明确了。
DFS:其实,DFS 的递归用起来是很简单的方法,就是在搜索到符合要求的元素后,制造一个搜索函数(change())将所有连通的相关元素改变成不符合要求的元素(例如将”1“改为”0“),改完之后返回初始的结点继续搜索元素判断,这样就能保证每个连通块都能只使累加器加一。不过,要特别注意边界问题,刚开始我还在疑惑为什么要考虑边界,后来自己用代码在编译器上试了一遍才发现,边界是保证函数不出错的重要内容。
非DFS:其实与DFS差不多,都是在标记相关要求的元素,再返回判断,不过所谓非DFS其实就是换成了for()循环,换汤不换药,就不继续赘述了。
PS:其实好像BFS也可以解决,但看的感觉没有DFS简洁,就没有刻意思考了
3.
南蛮图腾 - 洛谷 |
通过这个题我第一次听说了分治的概念,虽然不甚理解,但对这道题是有些许思路了。
其实这道题我个人感觉更像一个数学类型的题目,而且似乎没用搜索(可能单纯是老师想让我们接触分治),不过,这道题确实难到了我一段时间,我就不考虑其他,先简单说一下思路。
首先,这个题简单处在于特别的规律性以及单位字符图形(输出字符"\"时一定要用转义字符去输出,即:"\\"),那么就是考虑图形的变换了,通过观察我们能发现,第二行中间的空缺其实是倒置的单位字符图形,第三行开始,空缺图形变大一倍,所以,可以通过改变不同行数时单位图形的高和宽来达到输出的目的。这个思路其实是我在看过一些题解后得到的,之前我的思路很简单,利用了以前类似的经验,对除首行尾行的行,只在最前面和最后面输出图形,其余用空格填充;而首行和尾行填满。但有一说一,确实麻烦。
这是本周看题里,我理解最深的几道类型题,其他的虽然大抵看懂,但自己的思路多是依靠题解形成,总感觉自己的想法不够多,就不鹊巢鸠占了。
二.比赛总结
本周的两场比赛我都参加了,但很难过的是,两次都是差一点AC。每次都是所有主体完成搭建与编译以后发现有的结点没处理好,比如昨天的比赛中,我忘记设置一个返回上一级的代码加入交换的代码中,导致忘记两个数组的某个元素交换后剩下的元素没法返回没交换 的结点继续搜索。也就是说,对于搜索的回溯这方面,我的欠缺很大。另一方面,我又得再次提醒自己,一定要看注释,周五的那场比赛,我想的很好,本来想看看大佬题解是如何解决我的问题的,结果发现,人家利用注释的bug直接就输出了(我花了俩小时,人家四分钟),当时人很麻,所以一定要向自己强调:一定要阅读完所有题目!尤其是注释!
最后,就是心痛的发现,自己还是经验不足,一定要补足经验,看更多的题。
三.博客总结
这周自己看的题虽然不如上周多,但对所看题解的数量和理解程度都是远远超过上一周的。
而对于搜索,我不仅了解了自己在搜索的缺陷(回溯),也新学会了类似于分治,爬山法等等内容,这些内容更多的助力在了我今后对题思路的生成。
当然,我也新接触了连通块这一类问题,(其实看到的新题不少,但感觉其实就是对过去一些题的加深变形,故不单独成类列举),现在,我已经可以利用搜索解决一些经典的DFS,BFS,最优化方案选择,连通块和规律图形排布等问题。熟练解决确实还不至于(至少是在自己回溯问题解决之前)。
总的下来,感觉接触的东西越多,发现自己懂得越少,越需要不断的补足缺漏,而且碰到的题越来遇难,自己需要熟练掌握的知识也越多越难,因此,自己应当要不断增加自己在领域内的学习时间,自己现在实力与阅历不够,看着别人在不断进步,自己也得不断进步,不能落后。前路确实艰难,但也总得负重前行呐。
又是几个小时几千字,这周博客没打太多代码,就这样结束吧。