您的位置:首页 > 其它

homework-04

2013-10-27 23:43 495 查看
一. 程序设计想法:

于是这次我实在是懵了...真的不会啊...(好在后来得知是个np问题)...

于是听从老师的建议,先从判定算法写起...

于是第一反应这是一个八方搜索啊

我从1~n,1~n表示一个二维字符矩阵,不从0开始的好处是防止溢出。

dfs(int x,int y,int direct,int num,int k)

分别表示此时搜到的坐标为(x,y),方向为direct(若为0则启动1~8循环方向),num为此时序列符合第几个单词(若为-1则启动1~count循环判定符合与否),k表示此时为第num个单词的第k个字母(当k==第num个单词长度时,则搜到完整单词)。

似乎就是一个全排列类似的写法。

需要记录的就是给定的count个单词是否被覆盖且仅被覆盖一次,二维字符矩阵中的每个字符被覆盖了多少次,是否4个顶点都被覆盖,是否有一行或一列没有被覆盖,是否8个方向都满足数量。

似乎简单但写起来却挺费劲。前几天刚写了个数独的解法,用的就是类似的搜索...事实证明可行...

但是

同组小伙伴王文涛提出:我为什么不能暴力一下? 就是对每一个字符进行和给定字符串第一个字符匹配,如果相同则八方暴力搜索。

真暴力!但似乎和搜索的时间复杂度差不多0.0

于是就给他搞了...

我来写生成算法T.T怎么能这样!

还是老办法,分步写...

第一个模块:字符串预处理,把中间空格去掉

int StringJudge(int direct,int num,int x,int y)
{
int i,flag = 0,res = 0;
if (direct == 0)
{
if (y >= StringLength[num])
{
for (i = 0;i < StringLength[num];i++)
if (OutputMatrix[x][y - i] != ' '
&& OutputMatrix[x][y - i] != StringInput[num][i]) flag = 1;
if (flag == 0) res = 1;
}
}
if (direct == 1)
{
if (x >= StringLength[num])
{
for (i = 0;i < StringLength[num];i++)
if (OutputMatrix[x - i][y] != ' '
&& OutputMatrix[x - i][y] != StringInput[num][i]) flag = 1;
if (flag == 0) res = 1;
}
}
if (direct == 2)
{
if ((StringLength[num] + x) <= maxN && (StringLength[num] + y) <= maxN)
{
for (i = 0;i < StringLength[num];i++)
if (OutputMatrix[x + i][y + i] != ' '
&& OutputMatrix[x + i][y + i] != StringInput[num][i]) flag = 1;
if (flag == 0) res = 1;
}
}
if (direct == 3)
{
if (x >= StringLength[num] && y >= StringLength[num])
{
for (i = 0;i < StringLength[num];i++)
if (OutputMatrix[x - i][y - i] != ' '
&& OutputMatrix[x - i][y - i] != StringInput[num][i]) flag = 1;
if (flag == 0) res = 1;
}
}
if (direct == 4)
{
if (y >= StringLength[num] && (x + StringLength[num]) <= maxN)
{
for (i = 0;i < StringLength[num];i++)
if (OutputMatrix[x + i][y - i] != ' '
&& OutputMatrix[x + i][y - i] != StringInput[num][i]) flag = 1;
if (flag == 0) res = 1;
}
}
if (direct == 5)
{
if (x >= StringLength[num] && (y + StringLength[num]) <= maxN)
{
for (i = 0;i < StringLength[num];i++)
if (OutputMatrix[x - i][y + i] != ' '
&& OutputMatrix[x - i][y + i] != StringInput[num][i]) flag = 1;
if (flag == 0) res = 1;
}
}
return res;
}
void StringIntoMatrix(int direct,int num,int x,int y)
{
int i;
if (direct == 0)
{
for (i = 0;i < StringLength[num];i++) OutputMatrix[x][y - i] = StringInput[num][i];
}
if (direct == 1)
{
for (i = 0;i < StringLength[num];i++) OutputMatrix[x - i][y] = StringInput[num][i];
}
if (direct == 2)
{
for (i = 0;i < StringLength[num];i++) OutputMatrix[x + i][y + i] = StringInput[num][i];
}
if (direct == 3)
{
for (i = 0;i < StringLength[num];i++) OutputMatrix[x - i][y - i] = StringInput[num][i];
}
if (direct == 4)
{
for (i = 0;i < StringLength[num];i++) OutputMatrix[x + i][y - i] = StringInput[num][i];
}
if (direct == 5)
{
for (i = 0;i < StringLength[num];i++) OutputMatrix[x - i][y + i] = StringInput[num][i];
}
}
void MatrixProduce(int StringNum)
{
int StringDirect = StringNum % 6;
int i,j,flag = 0,suit;
for (i = 0;i < maxN;i++)
{
for (j = 0;j < maxN;j++)
{
if (OutputMatrix[i][j] == ' ' || OutputMatrix[i][j] == StringInput[StringNum][0])
{
suit = StringJudge(StringDirect,StringNum,i,j);
if (suit == 1)
{
StringIntoMatrix(StringDirect,StringNum,i,j);
flag = 1;
}
}
if (flag == 1) break;
}
if (flag == 1) break;
}
}


View Code
这样似乎就可以了...当然只要maxN足够大的话,肯定能够把所有字符串放进去,满足全部条件除没有一行一列都是无用字符。

对于那组比较少的数据:



于是空格就是随意填的字符...

需要注意的是,我设定的第一步要求最小的maxN要比最长单词长度大1。

对于那组比较多的数据:



我们能做到20*20的矩阵,这是我们程序能找到的最小解。

最下面两个数字代表总共多少个单词以及成功打印了多少个单词。

二. 时间安排:

预计时间5h实际用时6h
代码规范0.5h0.5h
具体设计0.5h1h
具体编码2.5h3h
代码复审0.5h0h
代码测试0.5h1h
测试报告0.5h0.5h
三. 官方样例测试:(测试程序为王文涛所写)

test1



test2



test3



test4我们试了很多种生成算法(改变不同走向),结果还是通不过检测。

后来............

MUM是无论如何也通不过测试的啊!!!

忽略...

test5



就是这样了...算是较优解吧...

检测代码请见王文涛blogs。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: