zoukankan      html  css  js  c++  java
  • hdu 5340 Three Palindromes(manacher)

    Three Palindromes

    http://acm.hdu.edu.cn/showproblem.php?pid=5340

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

    Problem Description
    Can we divided a given string S into three nonempty palindromes?
     
     
    Input
    First line contains a single integer T20 which denotes the number of test cases.

    For each test case , there is an single line contains a string S which only consist of lowercase English letters.1|s|20000
     
     
    Output
    For each case, output the "Yes" or "No" in a single line.
     
    Sample Input
    2 abc abaadada
     
    Sample Output
    Yes No
     
    Source
     
    Recommend
    hujie   |   We have carefully selected several similar problems for you:  6022 6021 6020 6019 6018 
     
    题意:
    判断是否能将字符串S分成三段非空回文串
    因为将整个字符串分为3段,所以字符串要有回文前缀、回文后缀
    对原串做一遍manacher
    pre[]记录回文前缀的结尾处,suf[]记录回文后缀的开始处
    枚举所有前缀结尾处,后缀开始处
    这样就可以锁定第二段
    如果第二段的终点的回文区间与第三段相接或覆盖,就可以
    注:以上均是在经manacher处理后的字符串上进行,即保证串长是奇数
     
    可以用bitset优化,01记录是否是回文前缀、后缀
    枚举第二段的回文中心,在第二段范围内,若前缀01序列和后缀翻过来的01序列有共同位置为1,则可以
     
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int t,n,len,p[41001];
    int pre[40001],suf[40001];
    char a[20001],s[41001];
    void manacher()
    {
    	n=0;
    	s[n++]='!';
    	for(int i=0;i<len;i++)
    	{
    		s[n++]='#';
    		s[n++]=a[i];
    	}
    	s[n++]='#';
    	s[n]='@';
    	int id=0,pos=0,x;
    	for(int i=1;i<=n;i++)
    	{
    		if(pos>i) x=min(p[id*2-i],pos-i);
    		else x=1;
    		while(s[i+x]==s[i-x]) x++;
    		if(i+x>pos) 
    		{
    			pos=i+x; 
    			id=i;
    		}
    		p[i]=x;
    	}
    }
    int main()
    {
    	scanf("%d",&t);
    	while(t--)
    	{
    		scanf("%s",a);
    		len=strlen(a);	
    		if(len<3)
    		{
    			printf("No
    ");
    			continue;
    		}
    		manacher();
    		int l=0,r=0;
    		for(int i=2;i<n-1;i++)//WA 1 :不能 从1到n ,1、n位置是#,不能算 
    		 {
    		 	if(i==p[i]) pre[++l]=i+p[i]-1;
    		 	if(i+p[i]-1==n-1) suf[++r]=i-p[i]+1;
    		 }
    		int t1,t2,mid;
    		bool ok=false;
    		for(int i=1;i<=l;i++)
    		{
    			for(int j=1;j<=r;j++)
    			{
    			 	t1=pre[i],t2=suf[j];
    			 	t1++;t2--;
    			 	if(t1>t2) continue;///////// WA 2
    			 	mid=t1+t2>>1;
    			 	if(mid+p[mid]-1>=t2) 
    			 	{
    			 		ok=true;
    			 		break;
    				}
    		 	}
    		 	if(ok) break;
    		}
    		if(ok) printf("Yes
    ");
    		else printf("No
    ");
    	}
    }
    

      

  • 相关阅读:
    python利用Trie(前缀树)实现搜索引擎中关键字输入提示(学习Hash Trie和Double-array Trie)
    利用trie树实现前缀输入提示及trie的python实现
    利用python实现简单词频统计、构建词云
    Xss-challenge-tour(1-10)
    CTFHub-SQL注入 思路
    Bugku-web40
    Buuctf-web-[极客大挑战 2019]HardSQL
    命令执行及代码执行漏洞
    CTFHub-RCE 思路&AWCTF部分web题
    upload-labs 11-12 00截断
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/6669167.html
Copyright © 2011-2022 走看看