Theme Section HDU - 4763(些许暴力)

题意:

  求出最长公共前后缀 不能重叠  而且 这个前后缀 在串的中间也要出现一次

解析:

  再明确一次next数组的意思:完全匹配的最长前后缀长度

  求一遍next 然后暴力枚举就好了

  

#include <iostream>
#include <cstdio>
#include <sstream>
#include <cstring>
#include <map>
#include <cctype>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <cmath>
#define rap(i, a, n) for(int i=a; i<=n; i++)
#define rep(i, a, n) for(int i=a; i<n; i++)
#define lap(i, a, n) for(int i=n; i>=a; i--)
#define lep(i, a, n) for(int i=n; i>a; i--)
#define rd(a) scanf("%d", &a)
#define rlld(a) scanf("%lld", &a)
#define rc(a) scanf("%c", &a)
#define rs(a) scanf("%s", a)
#define MOD 2018
#define LL long long
#define ULL unsigned long long
#define Pair pair<int, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define _  ios_base::sync_with_stdio(0),cin.tie(0)
//freopen("1.txt", "r", stdin);
using namespace std;
const int maxn = 1e6+10, INF = 0x7fffffff;
int nex[maxn];

void get_next(char *s)
{
    int len = strlen(s);
    int j = 0, k = -1;
    nex[0] = -1;
    while(j < len)
    {
        if(k == -1 || s[j] == s[k])
            nex[++j] = ++k;
        else
            k = nex[k];
    }
}

int kmp(char *s, char *t, int len1, int len2) //串1  串2  串1的长度  串2的长度
{
    int i, j = 0;
    if(len1 == 1 && len2 == 1)
    {
        if(s[0] == t[0])
            return true;
        else
            return false;
    }
    for(int i=0; i<len1; i++)
    {
        while(j > 0 && s[i] != t[j])
            j = nex[j];
        if(s[i] == t[j])
            j++;
        if(j == len2)
            return true;
    }
}

char s[maxn];
char s2[maxn];
int main()
{
    int T;
    rd(T);
    while(T--)
    {
        rs(s);
        get_next(s);
        int len = strlen(s);
        if(!nex[len]){
            cout<< "0" <<endl;
        }
        else
        {
            int tmp = nex[len];
            while(tmp)
            {
                if(tmp*3 > len) //如果当前长度大于三倍 那么就用次长来匹配
                {
                    tmp = nex[tmp];
                    continue;
                }
                for(int i=0; i<tmp; i++)    //暴力取出那段子串
                    s2[i] = s[i];
                if(kmp(s+tmp, s2, len - 2*tmp, tmp))
                {
                    cout<< tmp <<endl;
                    break;
                }
                tmp = nex[tmp];
            }
        }
    }

    return 0;
}

原文地址:https://www.cnblogs.com/WTSRUVF/p/9486000.html

时间: 2025-01-04 05:31:12

Theme Section HDU - 4763(些许暴力)的相关文章

HDU 4763:Theme Section(KMP)

http://acm.hdu.edu.cn/showproblem.php?pid=4763 Theme Section 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 progr

hdu 4763 Theme Section (简单KMP)

Theme Section Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1184    Accepted Submission(s): 621 Problem Description It's time for music! A lot of popular musicians are invited to join us in t

【HDOJ 4763】 Theme Section (KMP+strstr)

[HDOJ 4763] Theme Section Theme Section Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1999    Accepted Submission(s): 947 Problem Description It's time for music! A lot of popular musicians a

hdu4763 Theme Section

地址:http://acm.hdu.edu.cn/showproblem.php?pid=4763 题目: Theme Section Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3491    Accepted Submission(s): 1623 Problem Description It's time for music!

HDU 4499 Cannon (暴力搜索)

题意:在n*m的方格里有t个棋子,问最多能放多少个炮且每个炮不能互相攻击(炮吃炮) 炮吃炮:在同一行或同一列且中间有一颗棋子. #include <stdio.h> #include <iostream> #include <algorithm> #include <string.h> #include <queue> #include <math.h> #define M 50 #define LL long long using

HDU 4902 线段树||暴力

给定一个序列,两种操作 1:把一段变成x. 2:把一段每个数字,如果他大于x,就变成他和x的gcd,求变换完后,最后的序列. 线段树解法:用lazy标记下即可,优化方法还是很巧妙的, Accepted 4902 515MS 3308K 1941 B C++ #include "stdio.h" #include "string.h" struct node { int l,r,x;// 在叶子节点代表值,树节点代表成端更新的lazy操作. }data[400010]

HDU 4831 Scenic Popularity 暴力模拟

Scenic Popularity Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 340    Accepted Submission(s): 110 Problem Description 临近节日,度度熊们最近计划到室外游玩公园,公园内部包括了很多的旅游景点区和休息区,由于旅游景点很热门,导致景点区和休息区都聚集了很多人.所以度度熊

twisted高并发库transport函数处理数据包的些许问题

还是在学校时间比较多, 能够把时间更多的花在学习上, 尽管工作对人的提升更大, 但是总是没什么时间学习, 而且工作的气氛总是很紧凑, 忙碌, 少了些许激情吧.适应就好了.延续着之前对twisted高并发框架的学习, 自己重新写了一遍代码, 并开始在程序中实现自己的一些想法, 并不局限于最基本的操作, 以及官网上的实例, 因此就引出来了今天的问题.首先, 我需要阐述下我的想法:在命令行下启动twisted的服务器端程序, 以及客户端程序.同时在客户端程序中传入三个命令行参数, 其中一定要有clos

HDU 4961 Boring Sum 暴力

题意:对于所有的A[I],同时找到左边和右边离它最近且是它的倍数的数相乘最后加起来求和. 解题思路:n*sqrt(n)的算法,开始以为过不了,wa了两发因为lld I64d对拍一个小时发现一个小时前交的代码没错只是没变I64d,..具体思路是枚举每个a[i]的因子,找离它最近的那个更新,如果已经没更新就不用更新了.用两个辅助数组记录最近的就行. 解题代码: 1 // File Name: 1002.cpp 2 // Author: darkdream 3 // Created Time: 201