版权声明:转载请注明原出处啦QAQ(虽然应该也没人转载): https://blog.csdn.net/hzk_cpp/article/details/86301913
题目: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;
}