• 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;
    }
  • 相关阅读:
    oracle11g安装客户端检查先决条件失败
    WinForm textbox 只允许输入数字
    Oracle存储过程
    Oracle游标
    Oracle之PL/SQL流程控制
    Oracle 变量
    log4net 使用
    Python Matplotlib 画图显示中文问题
    Oracle 数据迁移到 SQL Server
    C结构体【转】
  • 原文地址:https://www.cnblogs.com/swm8023/p/2621288.html
Copyright © 2020-2023  润新知