LightOJ 1258 Making Huge Palindromes (回文&KMP)

http://lightoj.com/volume_showproblem.php?problem=1258

A string is said to be a palindrome if it remains same when read backwards. So, ‘abba‘, ‘madam‘ both are palindromes, but ‘adam‘ is not.

Now you are given a non-empty string S, containing only lowercase English letters. The given string may or may not be palindrome. Your task is to make it a palindrome. But you are only allowed to add characters at the right side of the string.
And of course you can add any character you want, but the resulting string has to be a palindrome, and the length of the palindrome should be as small as possible.

For example, the string is ‘bababa‘. You can make many palindromes including

bababababab

babababab

bababab

Since we want a palindrome with minimum length, the solution is ‘bababab‘ cause its length is minimum.

Input

Input starts with an integer T (≤ 10), denoting the number of test cases.

Each case starts with a line containing a string S. You can assume that 1 ≤ length(S) ≤ 106.

Output

For each case, print the case number and the length of the shortest palindrome you can make with S.

Sample Input

Output for Sample Input


4

bababababa

pqrs

madamimadam

anncbaaababaaa


Case 1: 11

Case 2: 7

Case 3: 11

Case 4: 19

Note

Dataset is huge, use faster I/O methods.

首先原串+翻转过来的串必然是一个回文串,但是二者在中间可以“融合”,而KMP算法恰好可以求出最大融合长度。

所以看翻转过来的串能匹配多少原串即可,答案就是len+(len-匹配个数)。

#include<bits/stdc++.h>
using namespace std;
const int mx=100007;

char t[mx],p[mx];
int f[mx],len;
void getfail()
{
    f[0]=f[1]=0;
    for(int i=1;p[i];i++)
    {
        int j=f[i];
        while(j&&p[i]!=p[j]) j=f[j];
        f[i+1]=(p[i]==p[j]?j+1:0);
    }
}

int findd()
{
    getfail();
    int j=0;
    for(int i=0;t[i];i++)
    {
        while(j&&p[j]!=t[i]) j=f[j];
        if(p[j]==t[i]) ++j;
    }
    return (len<<1)-j;
}
int main()
{
    //freopen("in.txt","r",stdin);
    int tt;
    scanf("%d",&tt);
    getchar();
    for(int cas=1;cas<=tt;cas++)
    {
        gets(t);
        len=strlen(t);
        reverse_copy(t,t+len,p);
        p[len]=0;
        printf("Case %d: %d\n", cas, findd());
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-29 05:23:54

LightOJ 1258 Making Huge Palindromes (回文&KMP)的相关文章

LightOJ 1258 Making Huge Palindromes(马拉车)

题目链接 题目大意:给一个串的右边添加尽量少的字符,使之成为回文串. ??如果一个串本身就是回文串的话,不需要添加任何字符它就是可以得到的最小的回文串了(废话).如果需要添加字符的,这个串的右半部分必需全部都为回文串(可能就一个字符),如果不是,那么光在右边添加字符定是不够的.所以我们用马拉车求一遍每个位置的最大回文串的长度.然后找一个最大的回文串,其右端位于串的最右端(其实也就是让左半部分最小,这样需要添加的字符就最少).那么怎么确定某个回文串的最右端在整个字符串的最右端呢?只要它的中心点到右

Light OJ 1258 Making Huge Palindromes 末尾添加最少字符变回文串

题目来源:Light OJ 1258 Making Huge Palindromes 题意:末尾添加最少的字符是使输入的串变成回文 输出长度 思路:直接KMP匹配出它和它反串的最大匹配 n减去它就是要添加的数量 #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 1000010; char a[maxn], p[maxn]; int

Codeforces Round #315 -Primes or Palindromes?(回文&amp;&amp;素数)

题目地址:Primes or Palindromes? 题意:给出p,q,A=p/q,求找出最大的n使得n以内的素数的个数<=A*n以内的回文串的个数. 思路:其实就是n以内的素数的个数*q<=n以内的回文串的个数*p.然而p/q的最大值为42,那么数到13000000就到达极限,所以我们直接可以从大的开始往小的一步一步的暴力枚举就可以(感觉窝还是太年轻..QAQ #include <stdio.h> #include <math.h> #include <str

HDOJ 3948 The Number of Palindromes 回文串自动机

看上去像是回文串自动机的模板题,就来了一发 The Number of Palindromes Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 1992    Accepted Submission(s): 694 Problem Description Now, you are given a string S. We want

hdu 1318 Palindromes(回文词)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1318 题意分析:输入每行包含一个字符串,判断此串是否为回文串或镜像串. 表面上看这道题有些复杂,如果能熟练运用字符数组的话,代码也颇为简洁.. /*Palindromes Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 657 Accepted

SP7586 NUMOFPAL - Number of Palindromes(回文树)

题意翻译 求一个串中包含几个回文串 题目描述 Each palindrome can be always created from the other palindromes, if a single character is also a palindrome. For example, the string "malayalam" can be created by some ways: malayalam = m + ala + y + ala + m malayalam = m

HDU 1544 Palindromes(回文子串)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1544 问题分析: 问题要求求出字符串的连续子串中的回文子串个数.首先,需要区分连续子串与子序列的区别. 连续子串为连续的字符组成的字符串:子序列需要满足在子序列中出现的字符的相对顺序与字符串中出现的相对顺序相同. 问题的解法:根据回文子串的长度分为奇数与偶数分为两种可能: 1.当回文子串长度为奇数时,中间的字符为任意字符,取除了字符串最左边与最右边的字符的其他字符,通过向两边拓展来判断 奇数回文子串

UVA 401 Palindromes(回文词)

 回文词 Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Practice UVA 401 Appoint description:  acmparand  (2013-07-07)Luke  (2014-01-20) System Crawler  (2015-05-10) Description A regular palindrome is a string of

[APIO2014] [Uoj103] [Bzoj3676] Palindromes回文串 [Manacher,后缀数组]

用Manacher算法枚举回文子串,每次在后缀数组排序后的后缀数组中二分,因为用某一后缀和其他子串分别求匹配的长度,匹配长度在排序后该后缀的两侧具有单调性(匹配长度为min{H[x]|i<=x<=j},所以对于查询min(H[x])用ST表O(n)预处理,O(1)查询即可.Manacher时间复杂度O(n),后缀数组复杂度O(nlogn),总复杂度O(nlogn).注意二分时的边界条件! #include <iostream> #include <cstdio> #in