POJ2185 Milking Grid 題解(KMP)
阿新 • • 發佈:2019-01-13
題目: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;
}