HDU 3068 http://acm.hdu.edu.cn/showproblem.php?pid=3068
题意:求一个字符串的最长回文串长度。
解法:manacher算法O(n)。
源代码:
#include<stdio.h>
#define M 110010
char a[M<<1],b[M];
int p[M<<1];
int min(int a,int b){
return a<b?a:b;
}
int main()
{
int i,n,id,maxId,maxL;
while(scanf("%s",&b[1])!=EOF){
for(i=1;b[i]!='\0';i++){
a[i<<1]=b[i];
a[(i<<1)+1]='#';
}
a[0]='?';a[1]='#';
n=((i-1)<<1)+2;a[n]='\0';
maxL=maxId=0;
for(i=1;i<n;i++){
if(maxId>i) p[i]=min(p[id*2-i],maxId-i);
else p[i]=1;
while(a[i+p[i]]==a[i-p[i]])
p[i]++;
if(p[i]+i>maxId){
maxId=p[i]+i;
id=i;
}
if(maxL<p[i]) maxL=p[i];
}
printf("%d\n",maxL-1);
}
return 0;
}
POJ 2402 Palindrome Numbers http://poj.org/problem?id=2402
题意:输出第i(1<=i<=2*10^9)个数字回文串。
好吧。。。这题整了好长时间,只推出了几个公式,但还是没有写出具体代码来,sad。。。所以无耻的在网上找了篇解题报告。。。解法如下。
解题方案:
(1)先求出第i个数字回文的位数k,当位数为k时,k位数字组成的回文数为
f(k)=9*10^((k-1)/2),可以根据这个公式计算出第i个数字回文由几个数字组成。
(2)计算出第i个数字回文在k位数字组成的回文中的排名x。
(3)计算出(k+1)/2位数字当中的最小值y,即1000···000;
(4)回文的左部为y+=x-1,减1的原因是y和y翻转后的数字组在一起也算一个回文。
(5)将y进行翻转即得到最终答案ans。
源代码:
#include<cstdio>
#include<cmath>
__int64 num[25]={0,9,18,108,198,1098,1998,10998,19998,109998,199998,1099998,1999998,10999998,19999998,109999998,199999998,1099999998,1999999998,10999999998};
void solve(__int64 n){
int len,i,k;
__int64 x,y;
for(i=1;;i++){
if(num[i]>=n){
len=i;
break;
}
}
x=n-num[i-1];
k=(len+1)/2;
y=1;
for(i=1;i<k;i++)
y*=10;
y+=x-1;
printf("%I64d",y);
if(len%2) y/=10;
while(y){
printf("%d",y%10);
y/=10;
}
printf("\n");
}
int main()
{
__int64 n;
while(scanf("%I64d",&n),n)
solve(n);
return 0;
}