Milking Grid 【POJ - 2185】【KMP】

版权声明:https://blog.csdn.net/qq_41730082 https://blog.csdn.net/qq_41730082/article/details/86490927

题目链接


  题意:用最小面积的矩形表示完整个区域,可以有多余。

举几个样例:

2 8
ABCDEFAB
AAAABAAA
 ans:12
2 9
accaccacc
accaccdac
 ans:18
2 9
accaccacc
abcdfsegk
 ans:18
2 9
accacacca
accacacca
 ans:5

可以大致自己推一下,就会理解了:

再来个:

3 3
asd
asd
ase
 ans:9

那么,举完了样例,就是怎么解这道题的问题了,一开始的想法就是利用GCD求最小的横向以及纵向的面积覆盖,但是…… WA了,然后继续想办法,既然是求最大公共周期,那么这一列以及对应的一排,应该有自己的最小周期,(没有就是字符串本身的长了),那么,我们枚举每个字符串的全体周期可能性,然后一一找到最小的即可:具体的话,看一下代码,就是这个意思,表述不清……QAQ


#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN = 1e4 + 5;
int R, C;
char s[maxN][80];
int vis[maxN], nex[maxN];
void cal_nex(int pos)
{
    nex[0] = nex[1] = 0;
    int k = 0;
    for(int i=2; i<=C; i++)
    {
        while(k>0 && s[pos][k+1] != s[pos][i]) k = nex[k];
        if(s[pos][k+1] == s[pos][i]) k++;
        nex[i] = k;
    }
    k = nex[C];
    while(k)
    {
        vis[C - k]++;
        k = nex[k];
    }
}
void oth_nex(int pos)
{
    nex[0] = nex[1] = 0;
    int k = 0;
    for(int i=2; i<=R; i++)
    {
        while(k>0 && s[k+1][pos] != s[i][pos]) k = nex[k];
        if(s[k+1][pos] == s[i][pos]) k++;
        nex[i] = k;
    }
    k = nex[R];
    while(k)
    {
        vis[R - k]++;
        k = nex[k];
    }
}
int main()
{
    while(scanf("%d%d", &R, &C)!=EOF)
    {
        memset(vis, 0, sizeof(vis));
        for(int i=1; i<=R; i++)
        {
            scanf("%s", s[i]+1);
            cal_nex(i);
        }
        int ans = C, res = R;
        for(int i=1; i<=C; i++) if(vis[i] == R) { ans = i;  break; }
        memset(vis, 0, sizeof(vis));
        for(int i=1; i<=C; i++) oth_nex(i);
        for(int i=1; i<=R; i++) if(vis[i] == C) { res = i;  break; }
        printf("%d\n", ans * res);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41730082/article/details/86490927