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 个方向的任一方向,同一单词摆放 ...
随机推荐
- WindowManager.LayoutParams.type属性
type 的取值: 应用程序窗口. public static final int FIRST_APPLICATION_WINDOW = 1; 所有程序窗口的“基地”窗口,其他应用程序窗口都 ...
- C++ STL之查找算法
C++STL有好几种查找算法,但是他们的用法上有很多共同的地方: 1.除了binary_search的返回值是bool之外(查找的了返回true,否则返回false),其他所有的查找算法返回值都是一个 ...
- bzoj2431: [HAOI2009]逆序对数列
dp. f[i][j]表示放置第i个数有j个逆序对的方案数. s[i][j]维护前缀和(f[i][0]~f[i][j]). 状态转移方程 f[i][j]=s[i-1][j]-s[i-1][max(j- ...
- UVa 11076 (有重元素的排列) Add Again
n个可重复的元素的排列一共有 = All种,其中 假设这些数依次为ai,每种数字有mi个. 从右往左考虑第d位数(d≥0),第i个数字出现的次数为,那么这个数字对所求答案的贡献为 其实可以先一次求出个 ...
- UVa 11526 H(n)
题意: long long H(int n){ long long res = 0; for( int i = 1; i <= n; i=i+1 ){ res = (res + n/i); } ...
- bzoj1412: [ZJOI2009]狼和羊的故事
空地之间开始没有连然后一直WA...题意混乱...尴尬. #include<cstdio> #include<cstring> #include<iostream> ...
- NoSQL 数据库系统对比
虽然SQL数据库是非常有用的工具,但经历了15年的一支独秀之后垄断即将被打破.这只是时间问题:被迫使用关系数据库,但最终发现不能适应需求的情况不胜枚举. 但是NoSQL数据库之间的不同,远超过两 SQ ...
- 把 HttpHandler.ashx 修改为 异步编程 异步操作
在 ASP.NET 中,所有的处理程序类必须实现 IHttpHandler 接口或者实现 IHttpAsyncHandler 接口,这两个接口的区别是前者是一个同步接口,后者是一个异步处理模式的接口. ...
- Mybatis学习——基本增删改查(CRUD)
Eclipse+Mybatis+MySql 1.所需jar 2.项目目录 3.源代码 package com.zhengbin.entity; public class Student { priva ...
- Java 如何防止线程意外中止
Thread的run方法是不抛出任何检查型异常(checked exception)的,但是它自身却可能因为一个异常而被终止,导致这个线程的终结.最麻烦的是,在线程中抛出的异常即使使用try...ca ...