回文串专题

 

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;
}


 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值