Light OJ 1205 Palindromic Numbers (数位DP)

来源:互联网 发布:网络直播足球联赛 编辑:程序博客网 时间:2024/05/21 12:59

题意:问区间[l,r]内有多少个数是回文,不考虑前导0。

解析:其实是个搜索,i位到s位有多少个数字,s是中间位置。找出回文数字其实只要确定出中间位置,然后找出有多少个数。

[code]:

#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<algorithm>using namespace std;typedef long long LL;int bit[20],top;LL dp[20][20];LL dfs(int i,int s,bool e,bool z){    if(i == s) return !e;    if(!e&&!z&&dp[i][s]!=-1) return dp[i][s];    LL res = 0;    int d,u = e?bit[i]:9;    for(d = 0;d <= u;d++){        if(z&&d) res += dfs(i-1,i?(i-1)/2:-1,e&&(d==u),z&&(d==0));        else res += dfs(i-1,s,e&&(d==u),z&&(d==0));    }    return (e||z)?res:dp[i][s]=res;}int check(){    int i = (top-2)/2;    for(;i >= 0;i--){        if(bit[i]>bit[top-1-i]) return 1;        else if(bit[i]<bit[top-1-i]) return 0;    }    return 1;}LL solve(LL n){    top = 0;    for(;n;n/=10) bit[top++] = (int)(n%10);    return dfs(top-1,-1,1,1)+check();}int main(){    int i,j,cas,T;    scanf("%d",&cas);    memset(dp,-1,sizeof(dp));    for(T = 1;T <= cas;T++){        LL l,r;        scanf("%lld%lld",&l,&r);        if(l > r) swap(l,r);        printf("Case %d: %lld\n",T,solve(r)-(l?solve(l-1):0));    }    return 0;}


0 0
原创粉丝点击