KMP_next陣列應用_迴圈元_POJ2185_Milking Grid
阿新 • • 發佈:2018-11-09
思路分析:
設給定圖形可由AB子矩形重複而成, 稍一想便知, 給定圖形必定可由其最左上角的AB子矩形重複而成. 因此只需找到所有行(長度C)同時滿足S[1...k] = S[C - k + 1...C]的最大的k和所有列(長度為R)同時滿足T[1...m] = T[R - m + 1...R]的最大的m, 即為最小迴圈單元的面積, 具體實現如下AC程式碼所示:
//POJ2185_Milking Grid #include <iostream> #include <cstdio> #include <set> #include <algorithm> #include <cstring> using namespace std; const int MAXR = 1e4 + 5, MAXC = 80; char g[MAXR][MAXC]; int R, C; int rnext[MAXR][MAXC], cnext[MAXC][MAXR];//rnext:行next, cnext: 列next int cntNext[MAXR];//cntNext[i]:next[i]的個數 int main(){ scanf("%d %d", &R, &C); for(int i = 1; i <= R; ++i) scanf("%s", g[i] + 1); //計算行next for(int i = 1; i <= R; ++i){ rnext[i][1] = 0; for(int j = 2; j <= C; ++j){ int t = rnext[i][j - 1]; while(t && g[i][t + 1] != g[i][j]) t = rnext[i][t]; if(t > 0) rnext[i][j] = t + 1; else rnext[i][j] = g[i][1] == g[i][j]? 1: 0; } } //計算列next for(int i = 1; i <= C; ++i){ cnext[i][1] = 0; for(int j = 2; j <= R; ++j){ int t = cnext[i][j - 1]; while(t && g[t + 1][i] != g[j][i]) t = cnext[i][t]; if(t > 0) cnext[i][j] = t + 1; else cnext[i][j] = g[1][i] == g[j][i]? 1: 0; } } //計算行next交集 for(int i = 1; i <= R; ++i) for(int t = rnext[i][C]; t; ++cntNext[t], t = rnext[i][t]); int rlen = C; for(int i = C; i >= 1; --i) if(cntNext[i] == R){ rlen = C - i; break; } memset(cntNext, 0, sizeof(cntNext)); for(int i = 1; i <= C; ++i) for(int t = cnext[i][R]; t; ++cntNext[t], t = cnext[i][t]); int clen = R; for(int i = R; i >= 1; --i) if(cntNext[i] == C){ clen = R - i; break; } cout << clen * rlen << endl; return 0; }