zoukankan      html  css  js  c++  java
  • poj 2185(二维kmp)

    题意:让你求一个最小的覆盖子矩阵。

    分析:首先第一点是确定的:那就是这个子矩阵肯定位于左上角,然后按行考虑,求出每一行可能的重复子串的长度,然后取所有行都存在并且长度最短的长度最为最小子矩阵的宽,

    最后按列队长度为宽的字符串进行一次kmp求出循环节的长度。

    代码实现:

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    using namespace std;
    int n,m,windth,height;
    char str[10005][80];
    int visited[80],next[10005];
    
    void solve()
    {
        int i,j;
        for(i=0;i<n;i++)
          str[i][windth]='';
        i=0;j=-1;next[0]=-1;
        while(i<n)//按列进行kmp求出最小子矩阵的高
        {
            if(j==-1||strcmp(str[i],str[j])==0)
            {
                i++;j++;
                next[i]=j;
            }
            else
                j=next[j];
        }
        height=n-next[n];
        printf("%d
    ",windth*height);
    }
    
    int main()
    {
        int i,j;
        int x,y;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            getchar();
            memset(visited,0,sizeof(visited));
            for(i=0;i<n;i++)//求出每一行都有的最小重复子串作为宽
            {
                scanf("%s",str[i]);
                for(j=m;j>=1;j--)
                {
                    x=0;y=0;
                    for(;str[i][x]!='';x++,y++)
                    {
                        if(y==j)
                         y=0;
                        if(str[i][x]!=str[i][y])
                         break;
                    }
                    if(str[i][x]=='')
                     visited[j]++;
                }
            }
            for(i=1;i<=m;i++)
             if(visited[i]==n)
              break;
            windth=i;
            solve();
        }
        return 0;
    }
  • 相关阅读:
    Redis基础-基本数据类型
    C#特性
    C#反射
    Json序列化
    动态添加文本框并获取文本框的值
    iframe中镶嵌html页,并获取html页中的方法
    获取url中的参数
    发送邮件
    数据导入Excel表格
    处理xml模块、configparser模块、hashlib模块、subprocess模块
  • 原文地址:https://www.cnblogs.com/jiangjing/p/3325151.html
Copyright © 2011-2022 走看看