传送门:http://lightoj.com/volume_showproblem.php?problem=1258
题目大意:给定一字符串,求最少向后补多少个字符使整个串变成回文串。
解题思路:
算法一:KMP求出原串和逆置串的最大连续的公共子串长度(要求位于原串的后部和逆置串的前部),以逆置串为模式串与原串进行匹配,找到最后失配的地方就是最大连续的公共子串。
算法二:Manacher,每次更新最大。
Code:
Manacher:
/* W w w mm mm 222222222 7777777777777 */
/* W w w w m m m m 222 22 7777 */
/* w w w w m m m m 22 777 */
/* w w w w m m m m 22 77 */
/* w w w w m m m m 222 77 */
/* w w w w m m m m 222 77 */
/* w w w w m m m m 222 77 */
/* w w w w m m m m 222 77 */
/* w w w w m m m m 222 77 */
/* ww ww m mm m 222222222222222 77 */
//#pragma comment(linker, "/STACK:102400000,102400000")
//C++
//int size = 256 << 20; // 256MB
//char *p = (char*)malloc(size) + size;
//__asm__("movl %0, %%esp\n" :: "r"(p));
//G++
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define REP(i,s,t) for(int i=(s);i<=(t);i++)
#define REP2(i,t,s) for(int i=(t);i>=(s);i--)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned long ul;
const int N=1000005;
int T;
char s[N];
char Ma[N*2];
int Mp[N*2];
void Manacher(char s[],int len)
{
int l=0;
Ma[l++]='$';
Ma[l++]='#';
for(int i=0; i'#';
}
Ma[l]=0;
int mx=0,id=0;
for(int i=0; ii?min(Mp[2*id-i],mx-i):1;
while(Ma[i+Mp[i]]==Ma[i-Mp[i]])Mp[i]++;
if(i+Mp[i]>mx)
{
mx=i+Mp[i];
id=i;
}
}
}
void debug(int len)
{
REP(i,0,2*len-1)
{
printf("Mp[%d]=%d\n",i,Mp[i]);
}
}
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("test.in","r",stdin);
#endif
int ca=1;
scanf("%d",&T);
while(T--)
{
scanf("%s",s);
int len=strlen(s);
Manacher(s,len);
int ans=0;
//debug(len);
REP(i,0,2*len+1)
{
if(i+Mp[i]==2*len+2)
{
ans=max(ans,Mp[i]-1);
}
}
printf("Case %d: %d\n",ca++,len+len-ans);
}
return 0;
}
KMP:
/* W w w mm mm 222222222 7777777777777 */
/* W w w w m m m m 222 22 7777 */
/* w w w w m m m m 22 777 */
/* w w w w m m m m 22 77 */
/* w w w w m m m m 222 77 */
/* w w w w m m m m 222 77 */
/* w w w w m m m m 222 77 */
/* w w w w m m m m 222 77 */
/* w w w w m m m m 222 77 */
/* ww ww m mm m 222222222222222 77 */
//#pragma comment(linker, "/STACK:102400000,102400000")
//C++
//int size = 256 << 20; // 256MB
//char *p = (char*)malloc(size) + size;
//__asm__("movl %0, %%esp\n" :: "r"(p));
//G++
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define REP(i,s,t) for(int i=(s);i<=(t);i++)
#define REP2(i,t,s) for(int i=(t);i>=(s);i--)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned long ul;
const int N=1000005;
int T;
char a[N],b[N];
int next[N];
void kmp_pre(char x[],int m,int next[])
{
int i,j;
j=next[0]=-1;
i=0;
while(iwhile(-1!=j && x[i]!=x[j])j=next[j];
next[++i]=++j;
}
}
int KMP_Count(char x[],int m,char y[],int n)
{
int i,j;
int ans=0;
kmp_pre(x,m,next);
i=j=0;
while(iwhile(-1!=j && y[i]!=x[j])j=next[j];
i++;
j++;
if(j>=m)
{
ans++;
j=next[j];
}
}
if(ans)
{
return m;
}
else
{
return m+m-j;
}
}
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("test.in","r",stdin);
#endif
int ca=1;
scanf("%d",&T);
while(T--)
{
scanf("%s",a);
memset(b,0,sizeof(b));
strcpy(b,a);
int len=strlen(b);
reverse(b,b+len);
printf("Case %d: %d\n",ca++,KMP_Count(b,len,a,len));
}
return 0;
}