zoukankan      html  css  js  c++  java
  • HDU 5510 Bazinga

    1. 笔记
    思路是:首先从前到后扫一遍,如果一个字符串不是后一个字符串的字串就把它标记一下(表示之后不会再扫它);再从后到前来看,很容易想到,如果从k到n都被未被标记过,而k-1被标记过,那么答案肯定是[k,n]里的一个数(当然,输出-1当且仅当k==1)。另外,如果答案是ans,那么[k,ans]都满足条件,(ans,n]都不满足条件。
    我看网上很多题解都是从暴力从n扫到1,甚至还有用strstr也A的。但k=n/2时复杂度是(O(n^2l))。保险起见我用KMP+二分,复杂度是(O(nlognl))
    2. 代码

    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    #define ms(arr,a) memset(arr,a,sizeof arr)
    #define debug(x) cout<<"< "#x" = "<<x<<" >"<<endl
    const int maxP=2005;
    int f[maxP];
    void get_fail(char P[])
    {
        int l=strlen(P);
        f[0]=f[1]=0;
        for(int i=1,j;i<l;++i)
        {
            j=f[i];
            while(j&&P[i]!=P[j])j=f[j];
            f[i+1]=P[i]==P[j]?j+1:0;
        }
    }
    char* kmp(char T[],char P[])
    {
        get_fail(P);
        int lT=strlen(T),lP=strlen(P);
        for(int i=0,j=0;i<lT;++i)
        {
            while(j&&T[i]!=P[j])j=f[j];
            if(T[i]==P[j])++j;
            if(j==lP)return T+(i-lP+1);
        }
        return NULL;
    }
    
    int n;
    char s[505][2005];
    int mark[505]={0};
    bool ok(int m)
    {
        for(int i=mark[m];i;)
        {
            if(!kmp(s[m],s[i]))return true;
            if(mark[i]==i)i--;
            else i=mark[i];
        }
        return false;
    }
    int bs(int l,int r)
    {
        int m;bool okl=ok(l),okr=ok(r);
        if(okl&&okr)return r;
        if(!okl&&!okr)return -1;
        if(!okl){r=r^l;l=r^l;r=r^l;}
        while(r-l>1||l-r>1)
        {
            m=(l+r)/2;
            if(ok(m))l=m;
            else r=m;
        }
        return l;
    }
    int main()
    {
        //freopen("Input.txt","r",stdin);
    	int T;scanf("%d",&T);
    	for(int Case=1;Case<=T;++Case)
        {
            scanf("%d",&n);
            rep(i,1,n)scanf("%s",s+i);
            rep(i,1,n-1)mark[i]=kmp(s[i+1],s[i])?mark[i-1]:i;mark[n]=mark[n-1];
            //rep(i,1,n)printf("%d ",mark[i]);printf("
    ");
            printf("Case #%d: %d
    ",Case,bs(mark[n-1]+1,n));//
        }
    }
    
  • 相关阅读:
    asp.net访问网络路径方法(模拟用户登录)
    C# List使用District去重复数据
    post跨域请求
    Win7 IIS配置 applicationHost.config 错误:无法识别的特性“setProfileEnvironment” 解决方法
    常见 SQL语句使用 增删改查
    wangEditor编辑器中解析html图文信息问题
    jQuery制作table表格布局插件带有列左右拖动效果
    vue 三目运算
    jQuery遍历 filter()方法
    js 的filter()方法
  • 原文地址:https://www.cnblogs.com/maoruimas/p/9579937.html
Copyright © 2011-2022 走看看