“谁想出来的这么缺德的题目啊!!!!”一个声音在我心中回荡
这个题目很早就在课堂上公布了,我和我的小伙伴都惊呆了!
这是个毛?根本无从下手的感觉
总是觉得这个小游戏不是程序能给出答案的,因为我的第一印象总是我们给出一种规则,然后程序根据规则摆放单词,这种事情很不靠谱。。
加上老师给的例子也让人惊呆,那个能摆放的更密集一点么???!!!
一节课的商讨和观察以后,我和我的小伙伴达成一致意见,从斜着的方向起手,应该很容易完成,于是长达N星期的第四次作业总算有个能开始的理由了。。
思路:
选出wordlist中最短的几个单词,这个“几”可以是任意的,一般可以定为一个wordlist中20%的单词,这是个不错的数字
比如一个40个的wordlist,我选出其中的8个最短的作为横竖排列的目标
优先斜向排列的原因是我们发现如果斜向排列那么主对角线方向和次对角线方向的单词会互相不影响
这是个伟大的发现!
如果我们能将32个单词全部斜向排列好,那么横向和纵向的排列的剩下的8个单词只需要填补空隙就行了~
按着这个思路我们写下了如下程序
PS:这次作业我实在是不知道怎么写,于是交给我的大神队友来完成排列的算法,而我负责写检查的算法,就是给出一个单词检索它是否有重复或者存在。
给出一个单词矩阵
通过find算法找到答案
给出一个更大的矩阵
得到答案
这是我的工作,写出的find函数给大神用来做检测
#include <cstdio> #include <cstring> #include <cstdlib> char st[100][100]; char s[100]; int n,m,l,flag; bool find() { int move[8][2]; move[0][1]=-1;move[0][0]=-1; move[1][1]=0;move[1][0]=-1; move[2][1]=-1;move[2][0]=-1; move[3][1]=1;move[3][0]=0; move[4][1]=-1;move[4][0]=0; move[5][1]=-1;move[5][0]=1; move[6][1]=0;move[6][0]=1; move[7][1]=1; move[7][0]=1; int fx,k,xx,yy; bool mi; int i,j; for (i=0;i<n;i++) for (j=0;j<m;j++) { if (st[i][j]!=s[0])continue; for (fx=0;fx<=7;fx++) { xx=i;yy=j;mi=false; for (k=1;k<l;k++) { xx+=move[fx][0]; yy+=move[fx][1]; if (xx==-1||yy==-1||xx==n||yy==m) {mi=true;break;} if (st[xx][yy]!=s[k]) {mi=true;break;} } if (!mi) return true; } } return false; } int main() { int i,j,k,x,y,t; memset(st,'\0',sizeof(st)); memset(s,'\0',sizeof(s)); freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); scanf("%d%d",&n,&m); for (i=0;i<n;i++) scanf("%s",st[i]); scanf("%s",s); l=strlen(s); flag=find(); if (flag) printf("有\n");else printf("没有\n"); return 0; }
大神写的算法代码我就不放了。。
我们一开始先做了斜向的
单词列表
只含斜向的生成图
由此可以看到:单词排布比较紧密,但是周边出现的空白部分也比较多,尤其在右侧和下侧
而我们留下了8个单词正好可以用横竖的方式填补这个空白,达到最终的效果。
我只能说我的小伙伴真的很厉害,他天天说自己是坑,不声不响把所有工作都做好了。
他很踏实,很能干,就是感觉有点不是很勤快,我知道大神都这样~~瞎搞搞就把事情搞定了~~