• LightOJ


    A palindromic number or numeral palindrome is a 'symmetrical' number like 16461 that remains the same when its digits are reversed. In this problem you will be given two integers i j, you have to find the number of palindromic numbers between i and j (inclusive).

    Input

    Input starts with an integer T (≤ 200), denoting the number of test cases.

    Each case starts with a line containing two integers i j (0 ≤ i, j ≤ 1017).

    Output

    For each case, print the case number and the total number of palindromic numbers between i and j (inclusive).

    Sample Input

    4

    1 10

    100 1

    1 1000

    1 10000

    Sample Output

    Case 1: 9

    Case 2: 18

    Case 3: 108

    Case 4: 198

    题意:求区间的回文串数量。

    思路:从两头向中间靠,前缀是否小于原数用tag表示,后缀是否小于原数用ok表示,注意后缀尽管后面的比原位大,但是前面的小一点可以抵消其效果。

    #include<bits/stdc++.h>
    #define ll long long
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    ll dp[20][20][2][2]; int d[20],cnt;
    ll get(int bg,int l,int r,int tag,bool ok)
    {
        if(r>l) return !tag||(tag&&ok);
        if(!tag&&dp[bg][l][tag][ok]) return dp[bg][l][tag][ok];
        int lim=tag?d[l]:9; ll res=0;
        rep(i,0,lim){
            if(bg==l&&i==0) continue;
            bool g=ok;
            if(ok) g=i<=d[r];
            else g=i<d[r];
            res+=get(bg,l-1,r+1,tag&&(i==lim),g);
        }
        return tag?res:dp[bg][l][tag][ok]=res;
    }
    ll cal(ll x)
    {
        if(x<0) return 0LL;if(x==0) return 1LL;
        ll res=1; cnt=0;
        while(x) d[++cnt]=x%10,x/=10;
        rep(i,1,cnt) res+=get(i,i,1,i==cnt,true);
        return res;
    }
    int main()
    {
        int T,C=0; ll L,R; scanf("%d",&T);
        while(T--){
            scanf("%lld%lld",&L,&R); if(L>R) swap(L,R);
            printf("Case %d: %lld
    ",++C,cal(R)-cal(L-1));
        }
        return 0;
    }

    有部分数组没有必要:

    #include<bits/stdc++.h>
    #define ll long long
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    ll dp[20][20]; int d[20],cnt;
    //tag维护前缀是否小于,ok维护后缀是否小于。维护二者不一样。
    ll get(int bg,int l,int r,int tag,bool ok)
    {
        if(r>l) return !tag||(tag&&ok);
        if(!tag&&dp[bg][l]) return dp[bg][l];
        int lim=tag?d[l]:9; ll res=0;
        rep(i,0,lim){
            if(bg==l&&i==0) continue;
            bool g=ok;
            if(ok) g=i<=d[r];
            else g=i<d[r];
            res+=get(bg,l-1,r+1,tag&&(i==lim),g);
        }
        return tag?res:dp[bg][l]=res;
    }
    ll cal(ll x)
    {
        if(x<0) return 0LL;if(x==0) return 1LL;
        ll res=1; cnt=0;
        while(x) d[++cnt]=x%10,x/=10;
        rep(i,1,cnt) res+=get(i,i,1,i==cnt,true);
        return res;
    }
    int main()
    {
        int T,C=0;ll L,R; scanf("%d",&T);
        while(T--){
            scanf("%lld%lld",&L,&R); if(L>R) swap(L,R);
            printf("Case %d: %lld
    ",++C,cal(R)-cal(L-1));
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Decimal 格式化输出( 去掉多余的0和点)
    HTML Character Sets
    生成下面的模块时,启用了优化或没有调试信息
    PJBLog的CSS模板图
    .NET 实例化顺序
    Live Mail 报错 0x80048820 可能的处理方式
    Windows下将Ldif文件导入OpenLdap时的中文转换问题
    DataGrid中动态添加列
    Sip协议栈消息层的设计与实现
    Prism学习笔记模块之间通信的几种方式
  • 原文地址:https://www.cnblogs.com/hua-dong/p/9980178.html
Copyright © 2020-2023  润新知