D1
原题链接
当时我是暴力过的d1
分别从两端取相等的字符,找到不同的后停下来,再从停下来的位置暴力查找前缀和后缀的最长回文串
代码:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
string a,s;
int query(int a,int b)
{
int nn=b-a+1;
if(nn%2==0)
{
int flag=1;
for(int i=0;i<nn/2;i++)
{
if(s[a+i]!=s[b-i])
{flag=0;break;}
}
return flag;
}
if(nn%2!=0)
{
int flag=1;
for(int i=0;i<nn/2+1;i++)
{
if(s[a+i]!=s[b-i])
{flag=0;break;}
}
return flag;
}
}
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>s;
int n=s.size();
if(n%2==0)
{
int ii=0,jj=0;
for(int i=0;i<n/2;i++)
{
if(s[i]==s[n-i-1])
{continue;}
if(s[i]!=s[n-i-1])
{
ii=i;
jj=n-i-1;
break;
}
}
if(ii==0&&jj==0)
{cout<<s<<endl;
continue;}
int zz,hh,z,h;
for(int i=jj;i>=ii;i--)
{
if(query(ii,i))
{zz=i-ii+1;z=i;break;}
}
for(int i=ii;i<=jj;i++)
{
if(query(i,jj))
{hh=jj-i+1;h=i;break;}
}
if(zz>=hh)
{
for(int i=0;i<=z;i++)
{cout<<s[i];}
for(int i=jj+1;i<n;i++)
{cout<<s[i];}
cout<<endl;
}
else
{
for(int i=0;i<ii;i++)
{cout<<s[i];}
for(int i=h;i<n;i++)
{cout<<s[i];}
cout<<endl;
}
}
if(n%2!=0)
{
int ii=0,jj=0;
for(int i=0;i<n/2;i++)
{
if(s[i]==s[n-i-1])
{continue;}
if(s[i]!=s[n-i-1])
{
ii=i;
jj=n-i-1;
break;
}
}
if(ii==0&&jj==0)
{cout<<s<<endl;
continue;}
int zz,hh,z,h;
for(int i=jj;i>=ii;i--)
{
if(query(ii,i))
{zz=i-ii+1;z=i;break;}
}
for(int i=ii;i<=jj;i++)
{
if(query(i,jj))
{hh=jj-i+1;h=i;break;}
}
if(zz>=hh)
{
for(int i=0;i<=z;i++)
{cout<<s[i];}
for(int i=jj+1;i<n;i++)
{cout<<s[i];}
cout<<endl;
}
else
{
for(int i=0;i<ii;i++)
{cout<<s[i];}
for(int i=h;i<n;i++)
{cout<<s[i];}
cout<<endl;
}
}
}
return 0;
}
这里n是奇数和偶数处理是一样的,只不过当时分开写了,所以显得代码有点长。。。
D2
跟D1思路大致相同,只不过需要manacher处理一下
代码:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int d[3000005],len;
void manacher(string s)
{
int mx=0,p=0;
for(int i=1;i<=len;i++)
{
if(mx>i)
d[i]=min(mx-i,d[2*p-i]);
else
d[i]=1;
while(s[i-d[i]]==s[i+d[i]])
{d[i]++;}
if(d[i]+i>mx)
{
mx=d[i]+i;
p=i;
}
}
}
int main()
{
int t;
string c;
cin>>t;
while(t--)
{
cin>>c;
len=0;
int n=c.size();
if(n==1){cout<<c<<endl;continue;}
string s="";
d[0]=0;
s+="@";len++;
for(int i=0;i<n;i++)
{
s+="#";len++;
s+=c.substr(i,1);len++;
}
s+="#";
for(int i=0;i<len+3;i++)
{d[i]=0;}
manacher(s);
//
int ii=0,jj=0;
for(int i=1;i<=len;i++)
{
if(s[i]!=s[len-i+1])
{ii=i;jj=len-i+1;break;}
}
if(ii==0&&jj==0){cout<<c<<endl;continue;}
int zz=0,hh=0,z,h;
for(int i=jj;i>=ii;i-=2)
{
int mid=(ii+i)/2;
if((d[mid]+mid-1)>=i)
{zz=i-ii+1;z=i;break;}
}
for(int i=ii;i<=jj;i+=2)
{
int mid=(i+jj)/2;
if((mid-d[mid]+1)<=i)
{hh=jj-i+1;h=i;break;}
}
if(zz>=hh)
{
for(int i=1;i<=z;i++)
{if(s[i]!='#'){cout<<s[i];}}
for(int i=jj+1;i<=len;i++)
{if(s[i]!='#'){cout<<s[i];}}
cout<<endl;
}
else
{
for(int i=1;i<ii;i++)
{if(s[i]!='#'){cout<<s[i];}}
for(int i=h;i<=len;i++)
{if(s[i]!='#'){cout<<s[i];}}
cout<<endl;
}
}
return 0;
}