poj2185(二维最小覆盖子串问题-KMP)

来源:互联网 发布:口袋竞拍源码 编辑:程序博客网 时间:2024/06/04 20:06

题意:给出一个二维的字符矩阵,问最小的可覆盖子矩阵大小。


解法:如果是一维的话,在KMP算法的Next数组中,len-Next[len]是一维的覆盖子串,如果len-Next[len]能整除len,则可恰好覆盖(即长度为len-Next[len]的前缀)。

           在二维的情况,每行每列求一个最小公倍数就可以了,并且公倍数不能大于本身总长度。


代码:

/***************************************************** author:xiefubao*******************************************************/#pragma comment(linker, "/STACK:102400000,102400000")#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <queue>#include <vector>#include <algorithm>#include <cmath>#include <map>#include <set>#include <stack>#include <string.h>using namespace std;#define eps 1e-8typedef long long LL;char s[11000][100];int row,col;int Next[11000];char tool[11000];int getNext(char *p){    int len=strlen(p);    int i=0;int j=Next[0]=-1;    while(i<len)    {        while(j!=-1&&p[i]!=p[j])j=Next[j];        Next[++i]=++j;    }    return len-Next[len];}int gcd(int a,int b){    return a==0?b:gcd(b%a,a);}int main(){  while(scanf("%d%d",&row,&col)==2)  {      for(int i=0;i<row;i++)        scanf("%s",s[i]);      long long r=1;      for(int i=0;i<row;i++)      {          for(int j=0;j<col;j++)            tool[j]=s[i][j];          tool[col]='\0';          int k=getNext(tool);          r=k/gcd(r,k)*r;          if(r>=col)          {              r=col;              break;          }      }      long long c=1;      for(int i=0;i<col;i++)      {          for(int j=0;j<row;j++)            tool[j]=s[j][i];          tool[row]='\0';          int k=getNext(tool);          c=k/gcd(c,k)*c;          if(c>=row)          {              c=row;              break;          }      }      cout<<c*r<<'\n';  }   return 0;}/*4 11abcdabcdabcefghefghefaabcdabcdabcefghefghefg*/

0 0
原创粉丝点击