Uva 12050 (POJ 2402) - Palindrome Numbers 解题报告(数学)

本文介绍了一种高效算法来找出序列中的第K个回文数,通过统计不同长度的回文数并使用二分查找的方法快速定位目标回文数。

A palindrome is a word, number, or phrase that reads the same forwards as backwards. For example, the name "anna" is a palindrome. Numbers can also be palindromes (e.g.151 or 753357). Additionally numbers can of course be ordered in size. The first few palindrome numbers are:1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, ...

The number 10 is not a palindrome (even though you could write it as010) but a zero as leading digit is not allowed.

Input 

The input consists of a series of lines with each line containing one integer valuei (1 <= i <= 2*109). This integer value i indicates the index of the palindrome number that is to be written to the output, where index1 stands for the first palindrome number (1), index2 stands for the second palindrome number (2) and so on. The input is terminated by a line containing0.

Output 

For each line of input (except the last one) exactly one line of output containing a single (decimal) integer value is to be produced. For each input valuei the i-th palindrome number is to be written to the output.

Sample Input 

1
12
24
0

Sample Output 

1
33
151

    解题报告:求第K个回文数。统计每段区间有多少个回文数,二分查找所在区间,计算即可。很容易找到规律,101,111,121,131,……,191,202,……,999。相当于是10-99的奇数位回文数,一共90个。1001,1111,1221,1331,……,1991,2002,9999。相当于10-99偶数位回文数。
    代码如下:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;

typedef long long LL;

LL ten[20];
LL num[20];
LL sum[20];

void init()
{
    ten[0]=1;
    for(int i=1;i<10;i++)
        ten[i]=ten[i-1]*10;

    for(int i=0;i<=20;i+=2)
        num[i] = num[i+1] = ten[i/2]*9;

    sum[0]=num[0];
    for(int i=1;i<=20;i++)
        sum[i]=sum[i-1]+num[i];
}

int str[1000];
int top;

void LLtoStr(LL n)
{
    top=0;
    while(n)
        str[top++]=n%10,n/=10;
}

void work(LL n)
{
    int pos = lower_bound(sum,sum+20,n)-sum;
    LL ans = ten[pos/2]+(pos>0?n-sum[pos-1]-1:n-1);

    LLtoStr(ans);
    for(int i=top-1;i>=0;i--) printf("%d",str[i]);
    for(int i=pos&1?0:1;i<top;i++) printf("%d",str[i]);
    puts("");
}

int main()
{
    init();

    LL n;
    while(cin>>n && n)
        work(n);
}

    PS:我WA了很多次,因为数组开成20,而循环终止条件写成i<=20。本次测试没问题,提交上去后就报错了。以后一定要注意数组的大小,在这个上面WA过很多次了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值