zoukankan      html  css  js  c++  java
  • POJ2185 Milking Grid [KMP应用]

      一道KMP的好题,可惜数据实在是太弱了。

      给出R*C的字符矩阵,问至少多大面积的小矩阵可以覆盖掉整个大矩阵。很容易想到的解法就是求出循环节然后求最大公倍数,但是这样就忽视了可以不用正好覆盖这个条件,比如aaabaa可以拆成aaab/aa,aaaba/a,aaabaa,而不一定非要拆成4的倍数。正确的做法是求出每一列可能拆分的长度,然后取所有列都可以分的长度中最小的。比如

      abcdeaa
      aaabaaa

      第一个串可以分的长度有5,7,第二个串可以分的长度有4,5,6,7,所以取5作为公共长度。至于怎么求一个字符串所有可以拆分的情况,用KMP处理一遍就可以了,然后从最后一列开始,取i=next[i]直到i=-1,这中间的i-next[i]值都是可取长度,比如aabaabaa,它的next数组是01012345,从最后一列开始,next[8]=5,有8-5=3可取,next[5]=2,有8-2=6可取,next[2]=1,有8-1=7可取,next[1]=0,有8-0=8可取,最终可取的数有3,6,7,8四个数。至于为什么这样做是可行的,想想next数组的性质就知道了,next[i]表示以i结尾的串的前缀和后缀的匹配程度。

      算出宽度后只要将每行的前width个字符作为一个整体,然后KMP求出最小循环节作为height,求出乘积即可。

    #include <stdio.h>
    #include <string.h>
    int r,c;
    char mz[10005][80];
    int ctot[80],next[10005];
    void kmp_next(char *s){
        memset(next,0,5*c);
        next[1]=0,next[0]=-1;
        for(int i=2,j=0;i<=c;i++){
            while(j>0&&s[j+1]!=s[i])j=next[j];
            if(s[j+1]==s[i])j++;
            next[i]=j;
        }
        for(int i=next[c];i!=-1;i=next[i]){
            ctot[c-i]++;
        }
    }
    int kmp_col(){
        memset(next,0,sizeof next);
        next[1]=0;
        for(int i=2,j=0;i<=r;i++){
            while(j>0&&strcmp(mz[j+1]+1,mz[i]+1))j=next[j];
            if(strcmp(mz[j+1]+1,mz[i]+1)==0)j++;
            next[i]=j;
        }
        return r-next[r];
    }
    int solve(){
        memset(ctot,0,sizeof ctot);
        for(int i=1;i<=r;i++){
            kmp_next(mz[i]);
        }
        int width=0;
        for(int i=1;i<=c;i++){
            if(ctot[i]==r){
                width=i;
                break;
            }
        }
        for(int i=1;i<=r;i++){
            mz[i][width+1]='\0';
        }
        return width*kmp_col();
    }
    int main(){
        while(scanf("%d%d",&r,&c)!=EOF){
            for(int i=1;i<=r;i++){
                scanf("%s",mz[i]+1);
            }
            int x=solve();
            printf("%d\n",x);
        }
        return 0;
    }

       

  • 相关阅读:
    Oracle 推出 ODAC for Entity Framework 和 LINQ to Entities Beta版
    Entity Framework Feature CTP 5系列文章
    MonoDroid相关资源
    MSDN杂志上的Windows Phone相关文章
    微软学Android Market推出 Web Windows Phone Marketplace
    使用 Visual Studio Agent 2010 进行负载压力测试的安装指南
    MonoMac 1.0正式发布
    Shawn Wildermuth的《Architecting WP7 》系列文章
    使用.NET Mobile API即51Degrees.mobi检测UserAgent
    MongoDB 客户端 MongoVue
  • 原文地址:https://www.cnblogs.com/swm8023/p/2620853.html
Copyright © 2011-2022 走看看