1. 程式人生 > >POJ2185 Milking Grid 題解(KMP)

POJ2185 Milking Grid 題解(KMP)

題目:POJ2185.
題目大意:給定一個矩陣,要求用一個最小的矩陣重複疊加來匹配這個矩陣(最小矩陣可以不完整),求這個最小矩陣的面積.

在網上看到了一個感覺上比較穩的做法,以每一行為一個字元跑一遍KMP得到一個最小迴圈節,以每一列為一個字元跑一遍KMP得到一個最小迴圈節,然後把這兩個最小迴圈節乘起來得到答案.

這道題在網上有很大的爭議,POJ資料太水大致很多錯誤的演算法也能過這道題,而且我不是很明白題目是最小矩陣重複疊加後是否要是一個矩陣,所以就這樣吧.

程式碼如下:

#include<cstdio>
#include<iostream>
#include
<algorithm>
using namespace std; #define Abigail inline void typedef long long LL; const int N=10000,M=75; char c[N+9][M+9]; int nxt[N+9],n,m; bool check0(int x,int y){ for (int i=1;i<=n;++i) if (c[i][x]^c[i][y]) return false; return true; } bool check1(int x,int y){ for (int i=
1;i<=m;++i) if (c[x][i]^c[y][i]) return false; return true; } int self_mate0(){ int j=0; nxt[1]=0; for (int i=2;i<=m;++i){ while (!check0(j+1,i)&&j>0) j=nxt[j]; if (check0(j+1,i)) ++j; nxt[i]=j; } return m-nxt[m]; } int self_mate1(){ int j=0; nxt[1]=0; for (
int i=2;i<=n;++i){ while (!check1(j+1,i)&&j>0) j=nxt[j]; if (check1(j+1,i)) ++j; nxt[i]=j; } return n-nxt[n]; } Abigail into(){ scanf("%d%d",&n,&m); for (int i=1;i<=n;++i) scanf("%s",c[i]+1); } Abigail outo(){ printf("%d\n",self_mate0()*self_mate1()); } int main(){ into(); outo(); return 0; }