poj 2402

来源:互联网 发布:淘宝网禁止出售保护 编辑:程序博客网 时间:2024/06/14 20:00

数位统计问题,求出第K个回文数字。定义dp[i][j]表示i位数字以j作为开始和结尾的回文数字个数,则dp[i][j]+=dp[i-2][k](k=0-9)。

然后从高位开始一次确定每一位的数字。一些中间变量要超long long。

#include<stdio.h>#include<algorithm>#include<iostream>#include<string.h>#include<math.h>using namespace std;const int inf=2000000000;long long sum[20],dp[30][25];int K;void init(){    for(int i=0;i<=9;i++)        dp[1][i]=dp[2][i]=1;    for(int i=3;i<=20;i++)        for(int j=0;j<=9;j++)        {            for(int k=0;k<=9;k++)            dp[i][j]+=dp[i-2][k];        }    sum[1]=9;    for(int i=2;i<=20;i++)    {        int t=0;        for(int j=1;j<=9;j++)            t+=dp[i][j];        sum[i]=sum[i-1]+t;    }}void count(int K){    int len,ans[30];    for(int i=1;i<=20;i++)        if(sum[i]>=K)        {            len=i; break;        }    int l=1,r=len;    long long res=sum[len-1];    while(l<=r)    {        int cnt=r-l+1,flag=0;        for(int i=(r==len?1:0);i<=9;i++)        {            if(res+dp[cnt][i]>=K)            {                ans[l]=ans[r]=i;                flag=1;l++;r--;            }            else res+=dp[cnt][i];            if(flag) break;        }    }    for(int i=1;i<=len;i++)        printf("%d",ans[i]);    printf("\n");}int main(){ //   freopen("test.txt","r",stdin);    init();    while(scanf("%d",&K) && K)        count(K);    return 0;}

 

原创粉丝点击