字符串专题:G - Milking Grid (二维kmp)

来源:互联网 发布:ubuntu 16.04 云下载 编辑:程序博客网 时间:2024/05/16 09:22
#include <stdio.h>#include <string.h>#define MAX 10010#define MIN 110//题意:给定一个n*m的字符矩阵,每行字符会有若干个相同的串组成,最后一个重复串不一定要完整。问这个矩阵可由面积最小为多少的矩阵组成。int len,next[MAX];int row[MAX],col[MIN];char str[MAX][MIN],rostr[MIN][MAX];int Kmp(char *str) {int i,j,len;len = strlen(str);i = 0,j = -1;next[i] = -1;while (i < len) {if (j == -1 || str[i] == str[j])i++,j++,next[i] = j;else j = next[j];}return len - next[len];//公共串长度,(最后一个重复串不一定要完整)}int gcd(int a,int b){return b==0 ? a: gcd(b,a%b);}int lcm(int n,int m) {return n / gcd(n,m) * m;}int main(){int i,j,k,m,n;int r,c;while (scanf("%d%d",&n,&m) != EOF) {r = c = 1;for (i = 0; i < n; ++i) {scanf("%s",str[i]);row[i] = Kmp(str[i]);}for (i = 0; i < n; ++i)for (j = 0; j < m; ++j)rostr[j][i] = str[i][j];//倒转一下矩阵for (j = 0; j < m; ++j)col[j] = Kmp(rostr[j]);for (i = 0; i < m; ++i)r = lcm(r,col[i]);//先由列判行,再由行判列(1 <= n <= 10,000 ,1 <= m <= 75)r = n < r ? n : r;for (i = 0; i < r; ++i)//最小重复矩阵一定在左上角,且不会超过r行。c = lcm(c,row[i]);c = m < c ? m : c;printf("%d\n",r * c);}return 0;}/*Sample Input5 15ABCDABCDABCDABCBBABBABBABBABBAABCDABCDABCDABCBBABBABBABBABBAABCDABCDABCDABC4 12ABABABABABABBBABBABBABBAABABABABABABBBABBABBABBASample Output24最小矩阵为:ABCDABCDABCDBBABBABBABBAcol[0]:len-next[len]=5-3=2col[1]:len-next[len]=5-4=1c=lcm(col)=2*1=2;row[0]:len-next[len]=15-11=4;row[1]:len-next[len]=15-12=3;r=lcm(row)=4*3=12;12最小矩阵为:ABABABBBABBA*/

原创粉丝点击