POJ2185 Milking Grid 题解(KMP)

版权声明:转载请注明原出处啦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;
}

猜你喜欢

转载自blog.csdn.net/hzk_cpp/article/details/86301913
今日推荐