zoukankan      html  css  js  c++  java
  • #219. 【NOI2016】优秀的拆分

     
    如果一个字符串可以被拆分为 AABBAABB 的形式,其中 AA 和 BB 是任意非空字符串,则我们称该字符串的这种拆分是优秀的。
    
    例如,对于字符串 aabaabaa,如果令 A=aabA=aab,B=aB=a,我们就找到了这个字符串拆分成 AABBAABB 的一种方式。
    
    一个字符串可能没有优秀的拆分,也可能存在不止一种优秀的拆分。比如我们令 A=aA=a,B=baaB=baa,也可以用 AABBAABB 表示出上述字符串;但是,字符串 abaabaa 就没有优秀的拆分。
    
    现在给出一个长度为 nn 的字符串 SS,我们需要求出,在它所有子串的所有拆分方式中,优秀拆分的总个数。这里的子串是指字符串中连续的一段。
    
    以下事项需要注意:
    
    出现在不同位置的相同子串,我们认为是不同的子串,它们的优秀拆分均会被记入答案。
    在一个拆分中,允许出现 A=BA=B。例如 cccc 存在拆分 A=B=cA=B=c。
    字符串本身也是它的一个子串。
    输入格式
    每个输入文件包含多组数据。输入文件的第一行只有一个整数 TT,表示数据的组数。保证 1≤T≤101≤T≤10。
    
    接下来 TT 行,每行包含一个仅由英文小写字母构成的字符串 SS,意义如题所述。
    
    输出格式
    输出 TT 行,每行包含一个整数,表示字符串 SS 所有子串的所有拆分中,总共有多少个是优秀的拆分。
    
    样例一
    input
    
    4
    aabbbb
    cccccc
    aabaabaabaa
    bbaabaababaaba
    
    output
    
    3
    5
    4
    7
    
    explanation
    
    我们用 S[i,j]S[i,j] 表示字符串 SS 第 ii 个字符到第 jj 个字符的子串(从 11 开始计数)。
    
    第一组数据中,共有 33 个子串存在优秀的拆分:
    
    S[1,4]=aabbS[1,4]=aabb,优秀的拆分为 A=aA=a,B=bB=b;
    
    S[3,6]=bbbbS[3,6]=bbbb,优秀的拆分为 A=bA=b,B=bB=b;
    
    S[1,6]=aabbbbS[1,6]=aabbbb,优秀的拆分为 A=aA=a,B=bbB=bb。
    
    而剩下的子串不存在优秀的拆分,所以第一组数据的答案是 33。
    
    第二组数据中,有两类,总共 44 个子串存在优秀的拆分:
    
    对于子串 S[1,4]=S[2,5]=S[3,6]=ccccS[1,4]=S[2,5]=S[3,6]=cccc,它们优秀的拆分相同,均为 A=cA=c,B=cB=c,但由于这些子串位置不同,因此要计算 33 次;
    
    对于子串 S[1,6]=ccccccS[1,6]=cccccc,它优秀的拆分有 22 种:A=cA=c,B=ccB=cc 和 A=ccA=cc,B=cB=c,它们是相同子串的不同拆分,也都要计入答案。
    
    所以第二组数据的答案是 3+2=53+2=5。
    
    第三组数据中,S[1,8]S[1,8] 和 S[4,11]S[4,11] 各有 22 种优秀的拆分,其中 S[1,8]S[1,8] 是问题描述中的例子,所以答案是 2+2=42+2=4。
    
    第四组数据中,S[1,4]S[1,4],S[6,11]S[6,11],S[7,12]S[7,12],S[2,11]S[2,11],S[1,8]S[1,8] 各有 11 种优秀的拆分,S[3,14]S[3,14] 有 22 种优秀的拆分,所以答案是 5+2=75+2=7。
    
    样例二
    见样例数据下载。
    
    样例三
    见样例数据下载。
    
    限制与约定
    对于全部的测试点,保证 1≤T≤101≤T≤10。以下对数据的限制均是对于单组输入数据而言的,也就是说同一个测试点下的 TT 组数据均满足限制条件。
    
    我们假定 nn 为字符串 SS 的长度,每个测试点的详细数据范围见下表:
    
    测试点编号    nn    其他约束
    12300300    SS中所有字符全部相同
    3420002000
    561010782020
    9103030
    11125050
    1314100100
    15200200
    16300300
    17500500
    1810001000
    1920002000
    203000030000
    时间限制:1.5s1.5s
    空间限制:512MB
    题干

    哈哈,第一次啥都没看就独立完成了一道不水的题(虽然只有95分)。

    希望考试时也能这样(部分分也是很重要的)。

    好吧说一下思路:

      首先每得到一个新的字符串,先预处理两个数组ok[i][j],b[i],分别表示,从i到 j是否是两个相同的字符串(也就是是否存在AA)。和以i开头有几个相连的相同字符串(也就是有几个BB)

      然后n^2扫一遍 ans+=(ok[i][j])*b[j];  就ok了

      

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<math.h>
    #include<cstdio>
    using namespace std;
    #define LL unsigned long long 
    #define MOD 1000000007
    #define base 211
    LL n,b[2009],ha[2009][2009];
    char s[2009];
    int T;
    bool ok[2009][2009];
    void first()
    {
        for(int i=1;i<=n;i++)
            for(int j=i;j<=n;j++)
                ha[i][j]=(ha[i][j-1]*base+(LL)s[j])%MOD;
    }
    int main(  )
    {
        scanf("%d",&T);
        while(T--)
        {
            cin>>(s+1);        
            memset(ok,0,sizeof(ok));
            memset(b,0,sizeof(b));
            memset(ha,0,sizeof(ha));
            
             n=strlen(s+1);first();
            for(int i=1;i<=n;i++)
            for(int l=1;i+l+l-1<=n;l++)        
                if(ha[i][i+l-1]==ha[i+l][i+l*2-1])
                    ok[i][i+l+l-1]=1,b[i]++;
            
            LL ans=0;
            for(int i=1;i<=n;i++)
            for(int l=2;l+i-1<=n;l++)
            if(ok[i][i+l-1])    ans+=b[i+l];
            cout<<ans<<endl;
        }
        return 0;
    }

      

  • 相关阅读:
    一步步学习SPD2010--第十三章节--管理SP Server环境的Web内容(2)--理解SP Server2010的Web内容管理
    一步步学习SPD2010--第十三章节--管理SP Server环境的Web内容(1)--创建一个发布网站
    一步步学习SPD2010--第十三章节--管理SP Server环境的Web内容
    一步步学习SPD2010--第十二章节--理解可用性和可接入性(8)--关键点
    亚马逊推自家云备份产品,第三方云备份厂商压力山大 中国存储网
    几何概率模型是什么
    宋浩《概率论与数理统计》笔记---1..1.1-1.1.3、概率论基本概念
    机器学习疑难---1、什么是多元线性回归
    最大似然估计线性回归实例
    Hopfield神经网络 简介
  • 原文地址:https://www.cnblogs.com/CLGYPYJ/p/7372140.html
Copyright © 2011-2022 走看看