题目要求:
第四次作业,构造一个方阵将指定单词填入
stage 1:每个单词只出现1次,且八个方向各至少有两个单词
stage 2:矩阵长宽相等
stage 3:方阵的四个角都要参与单词的构建
算法思路:
课上将这个题的时候我和薛大神讨论了一下,通过研读样例,我们认为大部分单词都是斜着填进方阵的,所以我们在用8个单词构造好边框后,将剩下单词按照四种对角线的方向依次填入,最后再扫一遍矩阵将矩阵压缩就好.但是这种方法无法满足长宽相等的条件.
前天想了一个简单粗糙的方法,虽然能够满足题目的所有要求,但是构造的方阵缺少美感,尤其是在我刚刚看了肖犇犇和鲁大师的博客之后,突然感受到了这个世界深深的恶意...
先按照如图所示在左上角构造两条对角线,覆盖了8个单词,4种对角线方向(可以简单的将单词逆序来实现)
注意在插入第二条对角线的时候需要判断第一条对角线的长度为奇数还是偶数,如果是奇数那么就需要+1(来保证已经构造的满足长=宽),同时标记变量flag=true,mark用来标记空出的这一列
然后根据单词总数的奇偶,分别剩下两个或者三个单词来进行特判
不进行特判的单词就一横一竖插入就好(同样简单的用逆序来实现方向不同)
如果总数为奇数,那么就剩下3个单词特判,如果flag=true,先将一个单词放入mark列,再将剩余两个单词放入右下角(为了满足四个角都在单词中);如果flag=false,那么将两个单词按照以前的方式一横一竖放入,最后一个单词放入右下角
如果总数为偶数,那么就剩下2个单词特判,如果flag=true,先将一个单词放入mark列,再将最后一个单词放入右下角;如果flag=false,那么就将这两个单词都放入右下角
这样,我们就满足了各个方向都》=2,矩阵长=宽,四个角都在单词中的条件,为了满足每个单词只出现一次的条件,我们认为这是小概率条件,全放单一字母就好(例如放辅音字母),当然还可以暴力放入后暴搜判断是否满足条件.
有一点需要注意的是,开始构造8个单词的对角线时,为了放置后续单词放入时交叉,我们选择每条对角线有一个最长的单词;同时为了满足矩阵尽量小,我们将总体的单词按照长度从小到大排序
最后为了展示效果好一点,做了一点点美工,设计了UI。
后来我们觉得这个方法有点挫...
有搞了另外一个方法,算法是这样:
通过遍历单词表进行深搜。
搜索之前预留3个单词满足题目条件。
搜索的过程中记录当前矩阵的长宽边界。
对于当前搜索的单词,我们枚举它能摆放的位置和方向(起始位置处于当前矩阵长宽边界内)。
如果当前的摆放使原本长宽的长度差增加,则不这么摆。
当枚举完最后一个单词时,判断当前长宽边界,如果相等,则完成搜索。
最后将预留的3个单词加入左下,右下,右上角(左上角必然有词)。
效果是这样
Personal Software Process Stages | 时间百分比(%) | 实际花费的时间 (分钟) | 原来估计的时间 (分钟) | |
Planning | 计划 | 2.0 | 45 | 60 |
· Estimate | · 估计这个任务需要多少时间,把工作细化并大致排序 | 2.0 | 45 | 60 |
Development | 开发 | 88.7 | 2000 | 1500 |
· Analysis | · 需求分析 (包括学习新技术) | 2.7 | 60 | 60 |
· Design Spec | · 生成设计文档 | 0 | 0 | 0 |
· Design Review | · 设计复审 (和同事审核设计文档) | 0 | 0 | 0 |
· Coding Standard | · 代码规范 (制定合适的规范) | 5.3 | 120 | 60 |
· Design | · 具体设计 | 5.3 | 120 | 60 |
· Coding | · 具体编码 | 62.1 | 1400 | 1200 |
· Code Review | · 代码复审 | 10.6 | 240 | 60 |
· Test | · 测试(自我们测试,修改代码,提交修改) | 2.7 | 60 | 60 |
Reporting | 总结报告 | 9.3 | 210 | 60 |
· Test Report | · 测试报告 | 5.3 | 120 | 0 |
· Size Measurement | · 计算工作量 | 1.3 | 30 | 0 |
· Postmortem & Improvement Plan | · 事后总结, 并提出改进 | 2.7 | 60 | 60 |
Total | 总计 | 100% | 总用时 | 总估计的用时 |
2255 | 1260 |