您的位置:首页 > 其它

poj 2185 Milking Grid

2014-02-28 21:22 274 查看
  给你一个字符矩阵,然后在这个矩阵中找子矩阵,要求这个子矩阵的字符数最少,且能用这个子字符串拼成包含该字符矩阵(或者就是该字符矩阵)的字符矩阵。

开始我理解的时候,觉得可以换这个子矩阵的方向,结果看着别人都是直接用原始方向,不知道是我读题不仔细还是这题的信息有缺省,反正这题如果子字符串能转动,

那么这题肯定很麻烦,但是如果不变方向,直接求每行的循环子串的字符数,然后求lcm所有行的循环子串的字符串。列也按照同样的方法进行处理,然后2个相乘就解决了。这里需要注意一点,如果这个lcm超过了行或者列的总长度,直接取长度就行。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int Maxr = 10010, Maxl = 80;

char str[Maxr][Maxl];
int r, l, next[Maxr], lent;

int get_next_r(int x) {
int i = 0, j = -1;
next[0] = j;
while(i < l) {
if(j == -1||str[x][j] == str[x][i])
{
i++, j++;
next[i] = j;
}
else
j = next[j];
}
return i - next[i];
}

int get_next_c(int x) {
int i = 0, j = -1;
next[0] = j;
while(i < r) {
if(j == -1||str[j][x] == str[i][x])
{
i++, j++;
next[i] = j;
}
else
j = next[j];
}
return i - next[i];
}

int gcd(int a, int b) {
return b ? gcd(b, a % b) : a;
}

int lcm(int a,int b) {
return a/gcd(a, b)*b;
}

int main(void)
{
while(scanf("%d%d",&r,&l)!=EOF) {
for(int i = 0; i < r; ++i)
{
scanf("%s",str[i]);
}
int lr = 1, ll = 1;
for(int i = 0; i < r; ++i) {
lr = lcm(lr,get_next_r(i));
}
if(lr > l)
lr = l;

for(int i = 0; i < l; ++i) {
ll = lcm(ll,get_next_c(i));
}
if(ll > r)
ll = r;
cout<<ll*lr<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: