homework-04 单词方阵
问题描述
本次作业的题目要求利用给定的一组单词生成一个矩阵,矩阵的每个位置由一个字母填充,单词表中的每一个单词可以匹配矩阵中一段连续的序列,这段序列可以是横向,纵向或者是45度斜角方向,单词可以由左向友匹配,也可以逆向匹配。题目将生成的矩阵分为3个等级,任意一个等级要求满足前一级所有要求。第一级要求每个方向上至少出现两个单词,总共四个方向,矩阵横纵规模可以不等,每个单词在矩阵中仅能被覆盖一次,不能存在一行或一列不被任何短语覆盖;第二级要求矩阵横纵相等;第三级要求四个角必须被覆盖。最后返回的矩阵期望能有尽可能小的规模。
问题分析
题目第一眼看上去非常困难,实际上也非常困难,形式上看三级要求应该是难度逐级递增的,但稍加分析我们就会发现实际上,第三级和第二级的要求很好满足,第三级只要开始的时候在四个角填上单词即可, 除非算法太过灵动,否则完全可以将新矩阵看成一个有限制条件的矩阵,对题目影响很小,而第二级要求则更容易满足,但第二级要求与第一级联系很紧,直接讨论第一级要求,每个方向上至少出现两个单词,这个要求要求单词列表中至少有8个单词,如果单词表元素太少,那么这条要求就对程序要求非常苛刻,设计者协调最优性和合法性的难度相当的大,每个单词仅能覆盖一次,对于这个要求而言,如果单词表中存在一定规模的短单词,如at,in,on,into,to,保证这条要求可能需要耗费大量的资源,对于into,to而言实际上只能覆盖into,而对于banana,an而言就不能保证合法性了;对于每一行每一列都必须被覆盖而言,则可以通过填满对角线来容易的保证。
解题思路
开始思考解题方案时,如果填入一个单词进去,另一个单词和其重叠填充的话就能更好的利用空间,但同时存在另一个问题,如果填充一个单词在某个位置必须符合大量已经填过的词的限制,那么必然导致效率低下, 且有很大可能难以填充,但填充单词做到效率尽可能快重叠尽可能高显然是不现实的。为了处理这个矛盾,我们采用了这样一种方式,在填充初期,尽量避免限制,在后期尽量实现重叠。矩阵上有这样一个性质,如果我们对矩阵奇偶染色生成棋盘,那么在斜线上奇偶是互不相交的。
如果将其旋转45度,就会得到上图效果,仅考虑斜着放的情况的话,在奇数格子填充单词时不会影响偶数格子的,因此我们的实现在一开始先将矩阵奇偶染色,旋转45度后生成新矩阵,分别在两个矩阵中进行填充,然后再组合起来再在原矩阵总进行纵向和横向的填充。
在上次课程,我们又得到了新的启发,如果一开始填一个很长的单词并以纵向的方式填在原矩阵中,它会对每一个方向上的填充都造成一个限制,但这个限制非常弱,很容易满足,这样可以解决一些长单词的填充问题,同样我们再旋转过后的子矩阵中采用同样的策略,这样有非常有利于将长单词放在尽量小的矩阵中。同时我们也注意到,如果一开始放两个同向的单词效果就大打折扣了,原先匹配的可能有26种,而放了两个之后可能就迅速飙升到了26*26种,因此放置一个应该是一个非常合适的选择。正因为短的单词更容易匹配,因而我们将单词按长度排序,在运行初期尽可能使用长的单词,以保证后期能更容易的匹配。原先测试上课提供的样例时我们的程序仅能生成20*20的方阵,在加入这项优化后,就可以跑出19*19的方阵。
一些细节
在保证四个角都有单词时我们讨论了两种方案,一是在算法初期就在四个角填充一个单词,二是在算法结束前在四个角填充一个单词,实践上这两种方案对程序影响非常小。
在进行空余格子填充时,我们采用填充辅音字母的策略,后来继而改进采取又去掉了填充的常见辅音字母。
个人开发进程
阶段 | 估计用时 | 实际用时 |
用时估计 | 5h | 6h |
代码规范 | 0.5 | 0.5 |
具体设计 | 0.5 | 1 |
具体编码 | 2.5 | 3 |
代码复审 | 0.5 | 1 |
代码测试 | 0.5 | 0.5 |
homework-04 单词方阵的更多相关文章
- 洛谷 P1101 单词方阵
题目链接 https://www.luogu.org/problemnew/show/P1101 题目描述 给一n×n的字母方阵,内可能蕴含多个"yizhong"单词.单词在方阵中 ...
- 洛谷P1101 单词方阵——S.B.S.
题目描述 给一nXn的字母方阵,内可能蕴含多个“yizhong”单词.单词在方阵中是沿着同一方向连续摆放的.摆放可沿着8个方向的任一方向,同一单词摆放时不再改变方向,单词与单词之间[color=red ...
- 单词方阵 洛谷 P1101
题目描述 给一nXn的字母方阵,内可能蕴含多个"yizhong"单词.单词在方阵中是沿着同一方向连续摆放的.摆放可沿着8个方向的任一方向,同一单词摆放时不再改变方向,单词与单词之间 ...
- P1101 单词方阵 简单dfs
题目描述 给一n \times nn×n的字母方阵,内可能蕴含多个“yizhong”单词.单词在方阵中是沿着同一方向连续摆放的.摆放可沿着 88 个方向的任一方向,同一单词摆放时不再改变方向,单词与单 ...
- 洛谷1101:单词方阵(DFS)
题目描述 给一n×nn \times nn×n的字母方阵,内可能蕴含多个"yizhong"单词.单词在方阵中是沿着同一方向连续摆放的.摆放可沿着888个方向的任一方向,同一单词摆放 ...
- 洛谷P1101 单词方阵【暴力】【字符串】
题目描述 给一n×nn \times nn×n的字母方阵,内可能蕴含多个“yizhong”单词.单词在方阵中是沿着同一方向连续摆放的.摆放可沿着 888 个方向的任一方向,同一单词摆放时不再改变方向, ...
- 【洛谷P1101】单词方阵
题目大意:给一 \(n \times n\) 的字母方阵,内可能蕴含多个 \("yizhong"\) 单词.单词在方阵中是沿着同一方向连续摆放的.摆放可沿着 8 个方向的任一方向, ...
- 洛谷P1101单词方阵
题目描述 给一n×n的字母方阵,内可能蕴含多个“yizhong”单词.单词在方阵中是沿着同一方向连续摆放的. 摆放可沿着 8个方向的任一方向,同一单词摆放时不再改变方向,单词与单词之间可以交叉,因此有 ...
- P1101 单词方阵
题目描述 给一 n \times nn×n 的字母方阵,内可能蕴含多个"yizhong"单词.单词在方阵中是沿着同一方向连续摆放的.摆放可沿着 88 个方向的任一方向,同一单词摆放 ...
随机推荐
- 安卓开发44:解决 INSTALL_FAILED_UID_CHANGED 等问题
apk无法卸载,一般可以下面的方法试一下: 1. 删除/data/app/(filename) 文件夹下的apk包 2. 删除/system/app/(filename) 文件夹下的apk包 3. 将 ...
- Linux设备管理之权限倾斜——mem、proc、devfs、sysfs、udev(下)
linux发展第一阶段 01devfs(linux2.6之前) 02udev(用户空间) 03sysfs(linux2.6之后,描述设备属性) linux发展第二阶段 01sysfs+udev(ude ...
- .net 程序员成长路线图?
https://www.zhihu.com/question/25474641 得看赵四本, @赵劼 推荐的. CLR via C# .net Essentials C# in Depth Frame ...
- windows安装TortoiseGit详细使用教程【基础篇】
标签:tortoisegit 环境:win8.1 64bit 安装准备: 首先你得安装windows下的git msysgit1.9.5 安装版本控制器客户端tortoisegit tortoise ...
- [反汇编练习] 160个CrackMe之011
[反汇编练习] 160个CrackMe之011. 本系列文章的目的是从一个没有任何经验的新手的角度(其实就是我自己),一步步尝试将160个CrackMe全部破解,如果可以,通过任何方式写出一个类似于注 ...
- vim 支持 markdown 语法
/************************************************************************* * vim 支持 markdown 语法 * 说明 ...
- Python - re - 正则表达式 - 怎么用
<python cookbook> - 1.18 - 一次完成多个替换 这个blog介绍正则,写得不错,而且,一如既往的‘长’. 1. re.escape(string) THIS,说明函 ...
- noip2002提高组题解
再次280滚粗.今天早上有点事情,所以做题的时候一直心不在焉,应该是三天以来状态最差的一次,所以这个分数也还算满意了.状态真的太重要了. 第一题:均分纸牌 贪心.(昨天看BYVoid的noip2001 ...
- UVa 11300 Spreading the Wealth 分金币
圆桌旁坐着 n 个人,每个人都有一定数量的金币,金币总数能够被 n 整除.每个人可以给他左右相邻的人一些金币,最终使得每个人的金币数目相等.你的任务是求出被转手的金币数量的最小值,比如 n = 4, ...
- Ejabberd源码解析前奏--配置
一.基本配置 配置文件将在你第一次启动ejabberd时加载,从该文件中获得的内容将被解析并存储到内部的ejabberd数据库中,以后的配置将从数据库加载,并且任何配置文件里的命令都会被添加到 ...