Topic link: https: //vjudge.net/problem/POJ-2185
The meaning of problems: r × c matrix given by the capital letters, seeking a minimal matrix such that the sub-matrix can be composed of a large matrix, but does not require large matrix consisting of just a small matrix, i.e., the boundary portion will be left vacant (see examples) .
Ideas:
each row treated as a character, and then find next row array of r, then r-nex [r] is the minimum cycle in a row unit section size ans1.
The treated as a character for each column, and then to seek next column array c, the c-nex [c] is the minimum size of the cell cycle as a section ans2.
That is the final answer ans1 * ans2. (Area of the sub-matrix)
AC Code:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxr=10005; const int maxc=80; char s[maxr][maxc]; int ans1,ans2,r,c,nex1[maxr],nex2[maxc]; bool check1(int i,int j){ for(int k=0;k<c;++k) if(s[i][k]!=s[j][k]) return false; return true; } bool check2(int i,int j){ for(int k=0;k<r;++k) if(s[k][i]!=s[k][j]) return false; return true; } void get_next1(){ int j; j=nex1[0]=-1; for(int i=1;i<r;++i){ while(j>-1&&!check1(i,j+1)) j=nex1[j]; if(check1(i,j+1)) ++j; nex1[i]=j; } } void get_next2(){ int j; j=nex2[0]=-1; for(int i=1;i<c;++i){ while(j>-1&&!check2(i,j+1)) j=nex2[j]; if(check2(i,j+1)) ++j; nex2[i]=j; } } int main () { scanf("%d%d",&r,&c); for(int i=0;i<r;++i) scanf("%s",s[i]); get_next1(); get_next2(); ans1=r-(nex1[r-1]+1); ans2=c-(nex2[c-1]+1); printf("%d\n",ans1*ans2); return 0; }