zoukankan      html  css  js  c++  java
  • 玲珑杯 第4次 String cut(暴力字符串)

    题意:给你长度为n(<=100000)的字符串,问你任意删除一个字符后得到循环节最多的数量是多少

    题解:最简单的想法就是枚举删除的字符,再kmp求循环节,但是时间复杂度为O(n*n)会超时

    因此我们需要这样,需要删除的字符我们不能枚举,只能通过一些特别的方法来寻找或者判断

    我们根据kmp求循环节的想法来枚举循环节长度(相当于是答案),因为循环节长度是(n-1)的因子少于log2(n)个

    所以我们枚举了循环节的长度后可以使用O(n)来判断长度为m的循环节是否满足条件

    此时我们可以这样想:先假设我们需要删除的字符在第一个循环节内,此时我们先找出[0,m]的字符,然后[m+1,2*m]与[0,n]

    进行枚举匹配,当不同时就将[0,n]这一个向后跳一个在比较(当然只能跳一次),否则当需要删除的字符在第一个循环节后面,

    这样我们[0,m-1]就一定是循环节,这样再与[0,n]枚举匹配判断就好了

    #include<set>
    #include<map>
    #include<queue>
    #include<stack>
    #include<cmath>
    #include<vector>
    #include<string>
    #include<cstdio>
    #include<cstring>
    #include<iomanip>
    #include<stdlib.h>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define eps 1E-8
    /*注意可能会有输出-0.000*/
    #define Sgn(x) (x<-eps? -1 :x<eps? 0:1)//x为两个浮点数差的比较,注意返回整型
    #define Cvs(x) (x > 0.0 ? x+eps : x-eps)//浮点数转化
    #define zero(x) (((x)>0?(x):-(x))<eps)//判断是否等于0
    #define mul(a,b) (a<<b)
    #define dir(a,b) (a>>b)
    typedef long long ll;
    typedef unsigned long long ull;
    const int Inf=1<<28;
    const ll INF=1ll<<60;
    const double Pi=acos(-1.0);
    const int Mod=1e9+7;
    const int Max=1e5-7;
    char str[Max];
    string tem;
    int Jud(int n,int dig,int num)//n长度 dig循环节长度 num循环节个数
    {
        tem.clear();
        for(int i=0; i<dig; ++i)//假设[0,m-1]为循环节
            tem+=str[i];
        int flag=0;
        for(int i=dig; i<n; ++i)
        {
            if(tem[(i+flag)%dig]!=str[i])//
            {
                if(flag==-1)
                {
                    flag=-2;
                    break;
                }
                else
                {
                    flag=-1;
                }
            }
        }
        if(flag!=-2)
            return 1;
        tem.clear();
        for(int i=dig+1; i<dig+dig+1; ++i)//[m+1,2*m]为循环节
            tem+=str[i];
    
        flag=0;
        for(int i=0; i<n; ++i)
        {
            if(tem[(i+flag)%dig]!=str[i])
            {
                if(flag==-1)
                {
                    flag=-2;
                    break;
                }
                else
                {
                    flag=-1;
                }
            }
        }
        if(flag!=-2)
            return 1;
            return 0;
    }
    int main()
    {
        int t,n;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            scanf("%s",str);
            for(int i=1; i<=n-1; ++i)//枚举循环节长度
            {
                if(i==n-1||(n-1)%i==0&&Jud(n,i,(n-1)/i))//判断
                {
                    printf("%d
    ",(n-1)/i);
                    break;
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    Navicat Premium 12.1.12.0破解版激活
    vConsole调试器
    使用DbFunctions来解决asp.net mvc ef按照日期分组数据
    谷歌浏览器如何安装CRX插件?crx离线插件安装方法
    ASP.NET MVC——CodeFirst开发模式
    Sql server 事务的两种用法
    SQL Server 存储过程
    JqueryMobile新手问题大全
    .net core 轻量级容器 ServiceProvider 源码分析
    Centos7 使用Docker 部署mssql 2017
  • 原文地址:https://www.cnblogs.com/zhuanzhuruyi/p/6034558.html
Copyright © 2011-2022 走看看