zoukankan      html  css  js  c++  java
  • hdu4763 Theme Section【next数组应用】

    Theme Section

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 5091    Accepted Submission(s): 2550


    Problem Description
    It's time for music! A lot of popular musicians are invited to join us in the music festival. Each of them will play one of their representative songs. To make the programs more interesting and challenging, the hosts are going to add some constraints to the rhythm of the songs, i.e., each song is required to have a 'theme section'. The theme section shall be played at the beginning, the middle, and the end of each song. More specifically, given a theme section E, the song will be in the format of 'EAEBE', where section A and section B could have arbitrary number of notes. Note that there are 26 types of notes, denoted by lower case letters 'a' - 'z'.

    To get well prepared for the festival, the hosts want to know the maximum possible length of the theme section of each song. Can you help us?
     
    Input
    The integer N in the first line denotes the total number of songs in the festival. Each of the following N lines consists of one string, indicating the notes of the i-th (1 <= i <= N) song. The length of the string will not exceed 10^6.
     
    Output
    There will be N lines in the output, where the i-th line denotes the maximum possible length of the theme section of the i-th song.
     
    Sample Input
    5 xy abc aaa aaaaba aaxoaaaaa
     
    Sample Output
    0 0 1 1 2
     
    Source
     
    Recommend
    liuyiding

    题意:

    有$n$个字符串,找到每个字符串中最长的一段子串。要求这段子串在字符串的开头,中间和结尾都出现过。输出子串长度。

    思路:

    果然题目做多了一看就能有思路。

    要在开头和结尾都出现过,显然这个串的长度不可能大于$next[len]$。

    因为$next[len]$表示的就是$S[1,len]$中,前缀和后缀匹配的最长的长度。

    然后我们就要去找中间的。

    现在我们已经知道$S[1,nxt[len]$和$S[len - nxt[len]+1,len]$是匹配的了,答案只能比他们更小

    对于$S[nxt[len],len-nxt[len]+1]$的部分,我们去找每一个位置对应的$next$。

    最大的那一个$next$就表示,可以找到的最长的一段既在开头出现又在中间出现的子串。

    这个最大值和$nxt[len]$的较小值就是答案。

    $len-nxt[len]+1$之后的部分为什么不找呢,因为如果找到了也是重叠了,画个图会发现这样是不可行的。

     1 #include<iostream>
     2 #include<bits/stdc++.h>
     3 #include<cstdio>
     4 #include<cmath>
     5 //#include<cstdlib>
     6 #include<cstring>
     7 #include<algorithm>
     8 //#include<queue>
     9 #include<vector>
    10 //#include<set>
    11 //#include<climits>
    12 //#include<map>
    13 using namespace std;
    14 typedef long long LL;
    15 typedef unsigned long long ull;
    16 #define N 100010
    17 #define pi 3.1415926535
    18 #define inf 0x3f3f3f3f
    19 
    20 const int maxn = 1e6 + 5;
    21 int n;
    22 char str[maxn];
    23 int nxt[maxn];
    24 
    25 void get_nxt(char *s)
    26 {
    27     int len = strlen(s + 1);
    28     nxt[1] = 0;
    29     for(int i = 2, j = 0; i <= len; i++){
    30         while(j > 0 && s[i] != s[j + 1])j = nxt[j];
    31         if(s[i] == s[j + 1])j++;
    32         nxt[i] = j;
    33     }
    34 }
    35 
    36 int main()
    37 {
    38     while(scanf("%d", &n) != EOF){
    39         for(int i = 0; i < n; i++){
    40             scanf("%s", str + 1);
    41             get_nxt(str);
    42             int len = strlen(str + 1);
    43             int mx = -1;
    44             //cout<<nxt[len]<<endl;
    45             for(int i = nxt[len]; i <= len - nxt[len] + 1; i++){
    46                 //cout<<nxt[i]<<endl;
    47                 mx = max(mx, nxt[i]);
    48             }
    49             printf("%d
    ", min(mx, nxt[len]));
    50         }
    51     }
    52     return 0;
    53 }
  • 相关阅读:
    VS中常用设置记录
    MSBUILD结合批处理编译
    Linq to XML 基本类
    在Winform和WPF中注册全局快捷键
    Unity 配置文件 基本设置
    C# 通用Clone
    三次样条插值特点与实现 (引用了一点别人代码,但做了改动!)
    修正短时自相关函数
    矩阵的基本运算
    去红眼不完善 MATLAB 代码
  • 原文地址:https://www.cnblogs.com/wyboooo/p/9991091.html
Copyright © 2011-2022 走看看