zoukankan      html  css  js  c++  java
  • POJ2541 Binary Witch [状态压缩]

      这题是在做KMP分类里做到的,网上搜到的题解也基本都是KMP解的。但这题根本不是KMP,在网上找了个KMP的程序,随便rand了10组数据,跑了10多秒。

      题意比较纠结,就是说给你一个长度为N的串S,找出S[k..k+t-1]=s[N-t+1..N],其中1<=t<=13,k<=N-t,有多个k满足时,选择t最大的并且最靠右的,令S[N+1]=S[k+t],如果找不到符合条件的的K,则S[N+1]='0'。

      正解应该是压缩状态,每个子串都由01组成,可以看作一个2进制数,因为t的范围<=13,所以用2^13就可以表示出所有的子串,用last[i][j]表示长度为i内容为j的子串的最晚结束位置。只要扫一遍数组就可以了,遇到长度为i内容为j的子串就可以刷新last[i][j]。这样在处理第i位的时候,last中就保存了从1~i-1为所有长度为1~13的子串的最后出现位置。这种解法的复杂度是O((N+M)*13)。

    #include <stdio.h>
    #include <string.h>
    
    int n,l;
    char s[1002000];
    int last[13][9000];
    int main(){
        while(scanf("%d%d",&n,&l)!=EOF){
            scanf("%s",s);
            memset(last,-1,sizeof last);
            for(int i=0;i<n+l-1;i++){
                int now=0,tmp=1;
                //从i=n开始写入数组的i+1位
                if(i>=n-1)s[i+1]='0';
                for(int j=0;j<13&&i-j>=0;j++){
                    int x=s[i-j]-'0';
                    if(x)now+=tmp;
                    tmp<<=1;
                    //从i=n开始写入数组的i+1位
                    if(i>=n-1&&last[j][now]!=-1)s[i+1]=s[last[j][now]+1];
                    //写入的同时更新last,这样每次在找i的时候存的就是1~i-1的所有长度为1~13的子串最后结束位置
                    last[j][now]=i;
                }
            }
            s[n+l]='\0';
            printf("%s\n",s+n);
        }
        return 0;
    }
  • 相关阅读:
    java占位符应用
    【QuickHit项目实例】
    【那些年关于java多态应用】
    【那些年关于MyEclipse的快捷键大全】
    那些年【深入.NET平台和C#编程】
    关于《网络电视精灵》项目
    VS2013常用快捷键
    关于C#的继承结论
    关于【项目经理评分】项目的代码分析
    序列化和发序列化
  • 原文地址:https://www.cnblogs.com/swm8023/p/2621288.html
Copyright © 2011-2022 走看看