zoukankan      html  css  js  c++  java
  • POJ2185 Milking Grid(KMP)

    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'.
     
    题意:在字符矩阵中找出一个最小子矩阵,使其多次复制所得的矩阵包含原矩阵
     
    分析:为了找到最小重复的子矩阵,我们需要找到最小重复的宽度和长度.  
    最小重复的宽度需要满足每一行,所以我们枚举了每种宽度满足的行数.
    最后找到最小重复的宽度.
    找最小重复的长度的时候,进行在竖直方向上,对满足最小重复宽度的前缀进行KMP的next操作
    找到最小重复的长度
     
    贴一下一位讲解详细的大佬:http://blog.sina.com.cn/s/blog_69c3f0410100tyjl.html
     
    代码如下
    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    char str[10010][80];
    char a[80];
    int f[10010];//用来统计最小重复长度是下标长度的行数有多少.
    int Next[10010];
    int r,c,i,j,p,q,kuan;
    void getNext()
    {
        int j, k;
        j = 0; k = -1; Next[0] = -1;
        while(j < r)
            if(k == -1 ||!strcmp(str[j],str[k])) //进行多个字符数组之间的KMP操作
                Next[++j] = ++k;
            else
                k = Next[k];
    
    }
    int main()
    {
        while(scanf("%d%d",&r,&c)!=EOF)
        {
            for(int i=0;i<r;i++)
                scanf("%s",str[i]);
                memset(f,0,sizeof(f));
            for(int i=0;i<r;i++){
               memcpy(a,str[i],sizeof(str[i]));
              for(int j=c;j>0;j--)
              {
                a[j]='';
                for(p=0,q=0;str[i][q];p++,q++)
                {
                    if(p==j)p=0;
                    if(a[p]!=str[i][q])break;
                }
                if(!str[i][q])f[j]++;//能够匹配到字符串末端 即循环节成立,进行计数
              }
            }
           for(i=1;i<=c;i++)  
            {
              if(f[i]==r)  //求得满足所有行数的最小重复长度
              {
                  kuan=i;
                  break;
              }
            }
           for(i=0;i<r;i++)str[i][kuan]='';// 满足最小重复的宽度的前缀中进行KMP操作
           getNext();
           printf("%d
    ",(r-Next[r])*kuan);//长*宽 即为最小的重复子矩阵
        }
        return 0;
    }
  • 相关阅读:
    随笔 Frida
    [转]某种传染病第一天只有一个患者,前五天为潜伏期,不发作也不会传染人 第6天开始发作,从发作到治愈需要5天时间,期间每天传染3个人 求第N天共有多少患者 Frida
    sql 将具有相同ID的多条记录组合成一条记录 Frida
    【转】小谈C#.NET下的爬虫(蜘蛛)技术 Frida
    ECMAScript基础1 Frida
    显示隐藏层 jquery Frida
    SQL语句备份和还原数据库
    Hello!Blog~
    23个MySQL常用查询语句
    SQL Server 2008压缩数据库日志文件
  • 原文地址:https://www.cnblogs.com/a249189046/p/7436254.html
Copyright © 2011-2022 走看看