• homework-04


    一. 程序设计想法:

    于是这次我实在是懵了...真的不会啊...(好在后来得知是个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怎么能这样!

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

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

     1 int StringPretreatment(int Temp)
     2 {
     3     int Length = strlen(StringInput[Temp]);
     4     for (int i = 0;i < Length;i++)
     5     {
     6         if (StringInput[Temp][i] == ' ')
     7         {
     8             for (int j = i + 1;j < Length;j++)
     9                 StringInput[Temp][j - 1] = StringInput[Temp][j];
    10             StringInput[Temp][Length - 1] = EOF;
    11             Length--;i--;
    12         }
    13     }
    14     return Length;
    15 }
    View Code

    第二个模块:字符串按长度排序(由于数量不多我就用冒泡了)

     1 void StringSort()
     2 {
     3     int i,j,k;
     4     char StringTemp[25];
     5     for (i = 0;i < StringCount - 1;i++)
     6         for (j = i + 1;j < StringCount;j++)
     7             if (StringLength[i] < StringLength[j])
     8             {
     9                 k = StringLength[i];
    10                 StringLength[i] = StringLength[j];
    11                 StringLength[j] = k;
    12                 strcpy(StringTemp,StringInput[i]);
    13                 strcpy(StringInput[i],StringInput[j]);
    14                 strcpy(StringInput[j],StringTemp);
    15             }
    16 }
    View Code

     我的想法是用2个横&2个竖填充四条边,保证每个单词占据一个顶点,构成一个“卍”(没有中间的十字)

    于是代码如下:

     1 void FirstStep()
     2 {
     3     int i,j;
     4     for (i = 0;i < maxN;i++)
     5         for (j = 0;j < maxN;j++) OutputMatrix[i][j] = ' ';
     6     for (i = 0;i < StringLength[0];i++)
     7         OutputMatrix[0][i] = StringInput[0][i];
     8     for (i = 0;i < StringLength[1];i++)
     9         OutputMatrix[maxN - 1][maxN - StringLength[1] + i] = StringInput[1][i];
    10     for (i = 0;i < StringLength[2];i++)
    11         OutputMatrix[maxN - StringLength[2] + i][0] = StringInput[2][i];
    12     for (i = 0;i < StringLength[3];i++)
    13         OutputMatrix[i][maxN - 1] = StringInput[3][i];
    14 }
    View Code

    接着继续生成字符矩阵,由于横向正&竖向正已经满足条件,于是我偷懒的不写这两种情况了,剩下的字符串都以剩下6种填充。

    我的办法是暴力填充,所选位置为此字符串满足填充条件的第一个位置,因此也就没法保证最小性,但是要是使用dfs枚举所有位置,时间肯定会爆掉。

    选取每个字符串走向的办法是对字符串序号取模,对应剩下6种走向。

      1 int StringJudge(int direct,int num,int x,int y)
      2 {
      3     int i,flag = 0,res = 0;
      4     if (direct == 0)
      5     {
      6         if (y >= StringLength[num])
      7         {
      8             for (i = 0;i < StringLength[num];i++)
      9                 if (OutputMatrix[x][y - i] != ' '
     10                 && OutputMatrix[x][y - i] != StringInput[num][i]) flag = 1;
     11             if (flag == 0) res = 1;
     12         }
     13     }
     14     if (direct == 1)
     15     {
     16         if (x >= StringLength[num])
     17         {
     18             for (i = 0;i < StringLength[num];i++)
     19                 if (OutputMatrix[x - i][y] != ' '
     20                 && OutputMatrix[x - i][y] != StringInput[num][i]) flag = 1;
     21             if (flag == 0) res = 1;
     22         }
     23     }
     24     if (direct == 2)
     25     {
     26         if ((StringLength[num] + x) <= maxN && (StringLength[num] + y) <= maxN)
     27         {
     28             for (i = 0;i < StringLength[num];i++)
     29                 if (OutputMatrix[x + i][y + i] != ' '
     30                 && OutputMatrix[x + i][y + i] != StringInput[num][i]) flag = 1;
     31             if (flag == 0) res = 1;
     32         }
     33     }
     34     if (direct == 3)
     35     {
     36         if (x >= StringLength[num] && y >= StringLength[num])
     37         {
     38             for (i = 0;i < StringLength[num];i++)
     39                 if (OutputMatrix[x - i][y - i] != ' '
     40                 && OutputMatrix[x - i][y - i] != StringInput[num][i]) flag = 1;
     41             if (flag == 0) res = 1;
     42         }
     43     }
     44     if (direct == 4)
     45     {
     46         if (y >= StringLength[num] && (x + StringLength[num]) <= maxN)
     47         {
     48             for (i = 0;i < StringLength[num];i++)
     49                 if (OutputMatrix[x + i][y - i] != ' '
     50                 && OutputMatrix[x + i][y - i] != StringInput[num][i]) flag = 1;
     51             if (flag == 0) res = 1;
     52         }
     53     }
     54     if (direct == 5)
     55     {
     56         if (x >= StringLength[num] && (y + StringLength[num]) <= maxN)
     57         {
     58             for (i = 0;i < StringLength[num];i++)
     59                 if (OutputMatrix[x - i][y + i] != ' '
     60                 && OutputMatrix[x - i][y + i] != StringInput[num][i]) flag = 1;
     61             if (flag == 0) res = 1;
     62         }
     63     }
     64     return res;
     65 }
     66 void StringIntoMatrix(int direct,int num,int x,int y)
     67 {
     68     int i;
     69     if (direct == 0)
     70     {
     71         for (i = 0;i < StringLength[num];i++) OutputMatrix[x][y - i] = StringInput[num][i];
     72     }
     73     if (direct == 1)
     74     {
     75         for (i = 0;i < StringLength[num];i++) OutputMatrix[x - i][y] = StringInput[num][i];
     76     }
     77     if (direct == 2)
     78     {
     79         for (i = 0;i < StringLength[num];i++) OutputMatrix[x + i][y + i] = StringInput[num][i];
     80     }
     81     if (direct == 3)
     82     {
     83         for (i = 0;i < StringLength[num];i++) OutputMatrix[x - i][y - i] = StringInput[num][i];
     84     }
     85     if (direct == 4)
     86     {
     87         for (i = 0;i < StringLength[num];i++) OutputMatrix[x + i][y - i] = StringInput[num][i];
     88     }
     89     if (direct == 5)
     90     {
     91         for (i = 0;i < StringLength[num];i++) OutputMatrix[x - i][y + i] = StringInput[num][i];
     92     }
     93 }
     94 void MatrixProduce(int StringNum)
     95 {
     96     int StringDirect = StringNum % 6;
     97     int i,j,flag = 0,suit;
     98     for (i = 0;i < maxN;i++)
     99     {
    100         for (j = 0;j < maxN;j++)
    101         {
    102             if (OutputMatrix[i][j] == ' ' || OutputMatrix[i][j] == StringInput[StringNum][0])
    103             {
    104                 suit = StringJudge(StringDirect,StringNum,i,j);
    105                 if (suit == 1)
    106                 {
    107                     StringIntoMatrix(StringDirect,StringNum,i,j);
    108                     flag = 1;
    109                 }
    110             }
    111             if (flag == 1) break;
    112         }
    113         if (flag == 1) break;
    114     }
    115 }
    View Code

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

    对于那组比较少的数据:

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

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

    对于那组比较多的数据:

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

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

    二. 时间安排:

    预计时间 5h 实际用时 6h
    代码规范 0.5h   0.5h
    具体设计 0.5h   1h
    具体编码 2.5h   3h
    代码复审 0.5h   0h
    代码测试 0.5h   1h
    测试报告 0.5h   0.5h

     三. 官方样例测试:(测试程序为王文涛所写)

    test1

    test2

    test3

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

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

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

    忽略...

    test5

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

    检测代码请见王文涛blogs。

  • 相关阅读:
    网站代码优化总结
    移动端 H5 页面注意事项
    js基础知识点收集
    2017-3-26 webpack入门(一)
    gulp教程
    less的使用
    微信小程序接口封装
    div上下左右居中几种方式
    前端知识点-面试
    call和apply
  • 原文地址:https://www.cnblogs.com/yimingzou/p/3391451.html
Copyright © 2020-2023  润新知