Mihahim has a string s. He wants to delete exactly one character from it so that the resulting string would be a palindrome. Determine if he can do it, and if he can, what character should be deleted.
The input contains a string s of length (2 ≤ |s| ≤ 200000), consisting of lowercase Latin letters.
If the solution exists, output «YES» (without quotes) in the first line. Then in the second line output a single integer x — the number of the character that should be removed from s so that the resulting string would be a palindrome. The characters in the string are numbered from 1. If there are several possible solutions, output any of them.
If the solution doesn't exist, output «NO» (without quotes).
evertree
YES 2
emerald
NO
aa
YES 2
题意:
给你一个串,问你在这个串中删除一个字符后这个串能否成为一个回文串,如果能还得输出需要删除的字符的位置。
解:
从左往右找,碰到第一个左右不同的字符时记一下位置,然后重新传一个删掉左或右字符后的字符串进行Manacher一下就行。
需要特判的是如果这个串本身就是回文串的处理。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int maxn=200005;
char str0[maxn],str[maxn<<1],str1[maxn];
int p[maxn<<1],len;int l,r;
void start()
{
str[0]='$',str[1]='#';
for(int i=0;i<len;i++)
{
str[i*2+2]=str0[i];
str[i*2+3]='#';
}
str[len*2+2]='\0';
}
int solve()
{
memset(p,0,sizeof(p));
int mx=0,id,ans=1;
for(int i=1;i<len*2+2;++i)
{
if(mx>i)p[i]=min(p[2*id-i],mx-i);
else p[i]=1;
for(;str[i-p[i]]==str[i+p[i]];p[i]++);
if(p[i]+i>mx)mx=p[i]+i,id=i;
if(p[i]>ans)ans=p[i];
}
return --ans;
}
int main()
{
int flag=0;
while(~scanf("%s",str1))
{
flag=0;int k;
int len1=strlen(str1);
int j=0;
for(int i=0;i<len1;i++)
{
str0[j]=str1[i];
j++;
}
len=j;
start();
if(solve()==len1)
{flag=1;k=len1/2+1;}
else{
for(int i=0;i<len1/2+1;i++)
{
if(str1[i]!=str1[len1-1-i])
{
l=i;r=len1-1-i;break;
}
}
int j=0;
for(int i=0;i<len1;i++)
{
if(i!=l)
{str0[j]=str1[i];j++;}
}
len=j;
start();
int ans=solve();
if(ans==len){flag=1;k=l+1;}
j=0;
for(int i=0;i<len1;i++)
{
if(i!=r)
{str0[j]=str1[i];j++;}
}
len=j;
start();
ans=solve();
if(ans==len){flag=1;k=r+1;}
}
//printf("L:%d R:%d K:%d",l,r,k);
if(flag==1)printf("YES\n%d\n",k);
else
printf("NO\n");
}
return 0;
}
<-------! 额,这道题也可以不用Manacher,直接跑一边就行,但比赛时没想着么多,直接就用Manacher感觉写起来简单点 !------->