Girls’ research
题目大意:
给出一个串,然后位移一下,让你求最长回文子串开始的位置和结束的位置,并且把串输出出来。
思路:
先求出位移量来,把原串改变,然后跑一遍马拉车,得出长度ans。如果回文子串长度ans为1输出NO,反之确定一下回文子串的中点坐标index,其左端点为(index-ans+1)/2-1,右端点为(index+ans-1)/2-1;
int l=index-ans+1,r=index+ans-1; //确定左右端点
printf("%d %d\n",l/2-1,r/2-1);
for(int i=l;i<=r;i++){
if(Newq[i]!=1&&Newq[i]!=-1){
Newq[i]=(Newq[i]-'a'-cha+26)%26+'a';
printf("%c",Newq[i]);
}
}
printf("\n");
// 或者
int l=index-ans+1,r=index+ans-1; //确定左右端点
printf("%d %d\n",l/2-1,r/2-1);
for(int i=l/2-1;i<=r/2-1;i++){
q[i]=(q[i]-'a'-cha+26)%26+'a';
printf("%c",q[i]);
}
}
printf("\n");
Code:
#include <iostream>
#include <cstdio>
#include<cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long int ll;
const int MAXN = 2e5+10;
char q[MAXN];
char Newq[MAXN<<1];
int len[MAXN<<1],cha;
int getNew(int n){
int i,cnt = 0;
Newq[cnt++] = -1;
Newq[cnt++] = 1;
for(i = 0; i < n; i++){
Newq[cnt++] = q[i];
Newq[cnt++] = 1;
}
Newq[cnt] = 2;
return cnt;
}
void Manacher(int n){
int i,mx = 0,po = 0,ans = 0,index;
memset(len,0,sizeof(len));
for(i = 1; i < n; i++){
if(mx > i) len[i] = min(mx-i,len[2*po-i]);
else len[i] = 1;
while(Newq[i-len[i]] == Newq[i+len[i]] ){
len[i]++;
}
if(i+len[i] > mx){
mx = i+len[i];
po = i;
}
if(len[i]-1>ans){
ans=len[i]-1;
index=i; // 最长回文子串中点坐标
}
}
if(ans==1){
printf("No solution!\n");
return ;
}
else{
int l=index-ans+1,r=index+ans-1; //确定左右端点
printf("%d %d\n",l/2-1,r/2-1); //确定左右端点
for(int i=l;i<=r;i++){
if(Newq[i]!=1&&Newq[i]!=-1){
Newq[i]=(Newq[i]-'a'-cha+26)%26+'a'; //偏移量
printf("%c",Newq[i]);
}
}
printf("\n");
}
}
int main(){
int t;
char ch;
while(~scanf("%s",&ch)){
// memset(q,0,sizeof q); 加上这行就超时了QAQ
memset(Newq,0,sizeof Newq);
scanf("%s",q);
cha=ch-'a';
int n=strlen(q);
int newn = getNew(n);
Manacher(newn);
}
return 0;
}