poj 2185 (最小重复字符矩阵)

版权声明: https://blog.csdn.net/weixin_39778570/article/details/81988241

Milking Grid
Time Limit: 3000MS Memory Limit: 65536K
Total Submissions: 9923 Accepted: 4312
Description

Every morning when they are milked, the Farmer John’s cows form a rectangular grid that is R (1 <= R <= 10,000) rows by C (1 <= C <= 75) columns. As we all know, Farmer John is quite the expert on cow behavior, and is currently writing a book about feeding behavior in cows. He notices that if each cow is labeled with an uppercase letter indicating its breed, the two-dimensional pattern formed by his cows during milking sometimes seems to be made from smaller repeating rectangular patterns.

Help FJ find the rectangular unit of smallest area that can be repetitively tiled to make up the entire milking grid. Note that the dimensions of the small rectangular unit do not necessarily need to divide evenly the dimensions of the entire milking grid, as indicated in the sample input below.

Input

  • Line 1: Two space-separated integers: R and C

  • Lines 2..R+1: The grid that the cows form, with an uppercase letter denoting each cow’s breed. Each of the R input lines has C characters with no space or other intervening character.
    Output

  • Line 1: The area of the smallest unit from which the grid is formed
    Sample Input

2 5
ABABA
ABABA
Sample Output

2

题意:给你一个字符矩阵,让你找出最小的子矩阵,使得这个子矩阵能够拼接成原矩阵,这里子矩阵可以使用一半(不完整重复,如题例)
解答:使用nxt数组分别求出两个维度上的最小重复行和重复列的长度,相乘即答案

AC code

#define _CRT_SBCURE_NO_DEPRECATE
#include <set>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>

using namespace std;

#define maxn 10005
#define maxm 80
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
int nxt[maxn];
char p[maxn][maxm];
int n, m,ans;

// 列相等 
bool samec(int i, int j){
    for(int k=1; k<=n; k++){
        if(p[k][i] != p[k][j]) return false;
    }
    return true;
}
// 行相等 
bool samer(int i, int j){
    for(int k=1; k<=m; k++){
        if(p[i][k] != p[j][k]) return false;
    }
    return true;
}
int main(){
    scanf("%d%d", &n,&m);
    for(int i=1; i<=n; i++) scanf("%s", &p[i][1]); // &注意输入问题
    nxt[0] = -1;
    int j = -1;

    for(int i=1; i<=m; i++){
        while(j>=0 && !samec(j+1, i)) j = nxt[j];
        nxt[i] = ++j;
    }
    ans = m-nxt[m]; // 最短重复列串(几列) 
    j = -1;
    // 由于nxt[0]为-1,所以不用初始化nxt 
    for(int i=1; i<=n; i++){
        while(j>=0 && !samer(j+1, i)) j = nxt[j];
        nxt[i] = ++j;
    }
    ans *= n-nxt[n];
    printf("%d\n", ans);
}

猜你喜欢

转载自blog.csdn.net/weixin_39778570/article/details/81988241
今日推荐