zoukankan      html  css  js  c++  java
  • poj2185 kmp求最小覆盖矩阵,好题!

    /*
    特征值k=m-next[m]就是最小循环节的长度,
    m%k就是去末尾遗留长度 
    */
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    
    char strs[10005][100];
    int r,c,w,h,f[1050],nxt[10005];//r是行,c是列 
    
    void kmp_pre1(char *s){//求一行的nxt数组 
        int nxtt[1005]={};
        int m=strlen(s);
        int i,j;
        i=0;j=nxtt[0]=-1;
        while(i<m){
            while(j!=-1 && s[i]!=s[j]) j=nxtt[j];
            nxtt[++i]=++j;
        }
        //把可行的长度都在f中+1
        int tmp=m-nxtt[m],k=0;
        while(k+tmp<=m){
            k+=tmp;
            f[k]++;
        }
        //剩下的串枚举一次开头就好 
        for(k=m%(m-nxtt[m]);k;k=nxtt[k]){
            f[m-nxtt[k]]++;
        }
    }
    
    void kmp_pre2(){
        memset(nxt,0,sizeof nxt);
        int i,j;
        i=0,j=nxt[0]=-1;
        while(i<r){
            while(j!=-1 && strcmp(strs[i],strs[j])!=0)
                j=nxt[j];
            nxt[++i]=++j;
        }
    }
    int main(){
        while(scanf("%d%d",&r,&c)==2){
            memset(f,0,sizeof f);//宽度为i的子串出现的次数 
            w=c,h=r; 
            
            for(int i=0;i<r;i++){
                scanf("%s",strs[i]);
                kmp_pre1(strs[i]);
            }
            for(int i=1;i<=c;i++)//找到矩阵最小宽度 
                if(f[i]==r){w=i;break;}
                
            for(int i=0;i<r;i++) 
                strs[i][w]='';//截取前w个字符 
                
            kmp_pre2();//获取在行之间的next数组 
            h=r-nxt[r];//h就是列上的特征值 
            
            printf("%d
    ",w*h); 
        }
        return 0;
    }
  • 相关阅读:
    数据库外键约束
    mysql查询数据
    操作mysql操作数据库
    自定义标签
    jstl标签
    getattibute 与 getparameter区别
    2017.3.2
    java中静态,抽象,接口,继承总结
    关于使用css伪类实现小图标
    动态生成的dom元素绑定事件
  • 原文地址:https://www.cnblogs.com/zsben991126/p/10273749.html
Copyright © 2011-2022 走看看