• poj2185 Milking Grid【KMP】


    Milking Grid
    Time Limit: 3000MS   Memory Limit: 65536K
    Total Submissions: 10084   Accepted: 4371

    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
    

    Hint

    The entire milking grid can be constructed from repetitions of the pattern 'AB'.

    Source

    题意:

    找一个最小循环子矩阵。最后一个循环节可以是不完整的。

    思路:

    【看题的时候完全没思路】

    首先我们可以找到一行的所有循环节,一行的最小循环节不一定是最小循环矩阵的行数,因为也许之后有的行时不以这个循环的。S[1~i]的最小循环节就是S[1~i-nxt[i]], S[1~i - nxt[nxt[i]]]是次小循环节,以此类推。我们统计一下每一行循环节的长度,当某个长度k出现的次数为r时,说明每一行都以[1~k]为循环,并且要找到最小的k。

    接着我们求列数。将一行的[1~k]作为整体,使用strcmp进行KMP匹配。可以找到列的最小循环节,即列数。

    相乘就是答案。

     1 #include <iostream>
     2 #include <set>
     3 #include <cmath>
     4 #include <stdio.h>
     5 #include <cstring>
     6 #include <algorithm>
     7 #include <vector>
     8 #include <queue>
     9 #include <map>
    10 using namespace std;
    11 typedef long long LL;
    12 #define inf 0x7f7f7f7f
    13 
    14 int r, c;
    15 const int maxn = 1e5 + 5;
    16 char s[maxn][80];
    17 int nxtrow[maxn][80], cntrow[maxn], nxtcol[maxn];
    18 
    19 int main()
    20 {
    21     while(scanf("%d%d", &r, &c) != EOF){
    22         memset(cntrow, 0, sizeof(cntrow));
    23         for(int i = 1; i <= r; i++){
    24             scanf("%s", s[i] + 1);
    25             nxtrow[i][1] = 0;
    26             for(int j = 2, k = 0; j <= c; j++){
    27                 while(k > 0 && s[i][j] != s[i][k + 1])k = nxtrow[i][k];
    28                 if(s[i][j] == s[i][k + 1])k++;
    29                 nxtrow[i][j] = k;
    30                 //cout<<j<<" "<<nxtrow[i][j]<<endl;
    31             }
    32             for(int j = c; j > 0; j = nxtrow[i][j]){
    33                 cntrow[c - nxtrow[i][j]]++;
    34             }
    35         }
    36         int row;
    37         for(int i = 1; i <= c; i++){
    38             if(cntrow[i] == r){
    39                 row = i;
    40                 break;
    41             }
    42         }
    43         //cout<<row<<endl;
    44         for(int i = 1; i <= r; i++){
    45             s[i][row + 1] = 0;
    46         }
    47 
    48         //nxtcol[1] = 0;
    49         for(int i = 2, j = 0; i <= r; i++){
    50             while(j > 0 && strcmp(s[i] + 1, s[j + 1] + 1) != 0)j = nxtcol[j];
    51             if(strcmp(s[i] + 1, s[j + 1] + 1) == 0)j++;
    52             nxtcol[i] = j;
    53             //cout<<i<<" "<<nxtcol[i]<<endl;
    54         }
    55 
    56         //cout<<nxtcol[r]<<endl;
    57         printf("%d
    ", (r - nxtcol[r]) * row);
    58     }
    59     return 0;
    60 }
  • 相关阅读:
    【BZOJ4367】[IOI2014]holiday假期 分治+主席树
    【BZOJ1264】[AHOI2006]基因匹配Match DP+树状数组
    【BZOJ4379】[POI2015]Modernizacja autostrady 树形DP
    【BZOJ4380】[POI2015]Myjnie 区间DP
    【BZOJ4382】[POI2015]Podział naszyjnika 堆+并查集+树状数组
    【BZOJ4384】[POI2015]Trzy wieże 树状数组
    【BZOJ4388】JOI2012 invitation 堆+线段树+并查集(模拟Prim)
    【BZOJ4550】小奇的博弈 博弈论
    Sqlserver列出所有数据库名,表名,字段名
    聚合与组合的区别?
  • 原文地址:https://www.cnblogs.com/wyboooo/p/9838955.html
Copyright © 2020-2023  润新知