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;
}

转载于:https://www.cnblogs.com/swm8023/archive/2012/08/03/2621288.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值