当前位置: 代码迷 >> 综合 >> POJ2185 (summer III N)
  详细解决方案

POJ2185 (summer III N)

热度:47   发布时间:2023-12-16 03:55:19.0

#include<stdio.h>#include<string.h>char s[10010][80];int next[10010];int main(){int i,j,x,y,r,c,f[80];char a[80];scanf("%d%d",&r,&c);for(i=0;i<c;i++)f[i]=0;for(i=0;i<r;i++){scanf("%s",s[i]);strcpy(a,s[i]);///将每行的每种重复子串长度都求出来for(j=c-1;j>0;j--){a[j]=0;///a数组为枚举s所有可能子串的数组,每次减少一位,判断减少后的字符串是否为原来的子串。for(x=0,y=0;s[i][y];x++,y++){///x,y分别记录子串和原串的位置if(!a[x])x=0;///if(a[x]!=s[i][y])break;}if(!s[i][y])f[j]++;}}///上面这段代可以参考学习for(i=0;i<c;i++)///找出所有行的最小相同的子串长度,为最小重复子矩阵的列数if(f[i]==r)break;x=i;///最小重复子矩阵的列数for(i=0;i<r;i++)s[i][x]=0;next[0]=-1;///按纵列求KMP的next函数,以求最小重复子矩阵的行数for(i=1,j=-1;i<r;i++){while(j!=-1&&strcmp(s[j+1],s[i]))j=next[j];if(!strcmp(s[j+1],s[i]))j++;next[i]=j;}///一个字符串为单位的kmp道理和字符串中单个字符的kmp一样,将!=改为strcmp(相同则返回值为0,不同则为非零),不过要注意将字符串末尾变成零。printf("%d\n",(r-1-next[r-1])*x);///行列相乘即为最终结果return 0;}

参考别人代码的时候加上了自己的一些感悟
主要分析参考链接:点击打开链接