LightOJ - 1205:Palindromic Numbers (数位DP&回文串)

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\n",++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\n",++C,cal(R)-cal(L-1));
    }
    return 0;
}

原文地址:https://www.cnblogs.com/hua-dong/p/9980178.html

时间: 2024-10-23 22:25:36

LightOJ - 1205:Palindromic Numbers (数位DP&回文串)的相关文章

lightOJ 1205(Palindromic Numbers数位DP)

Palindromic Numbers Time Limit: 2000MS Memory Limit: 32768KB 64bit IO Format: %lld & %llu Submit Status Description A palindromic number or numeral palindrome is a 'symmetrical' number like 16461 that remains the same when its digits are reversed. In

LightOJ 1205 - Palindromic Numbers (数位dp)

LightOJ 1205 - Palindromic Numbers (数位dp) ACM 题目地址:SPOJ MYQ10 Mirror Number 题意: 求[a,b]中回文的个数. 分析: 是SPOJ MYQ01的简单版...其实有非递归方法的. 代码: /* * Author: illuz <iilluzen[at]gmail.com> * Blog: http://blog.csdn.net/hcbbt * File: 1205.cpp * Create Date: 2014-08-

LightOJ 1205 Palindromic Numbers

数位DP.... Palindromic Numbers Time Limit: 2000MS Memory Limit: 32768KB 64bit IO Format: %lld & %llu [Submit]   [Go Back]   [Status] Description A palindromic number or numeral palindrome is a 'symmetrical' number like 16461 that remains the same when

LeetCode 5:Longest Palindromic Substring(最长回文串)

Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring. 思路一:(超时)简单的截取长度为length(length递减)的字串,判断其是否为回文串.第一个满足要求的回文串最长. public class S

Codeforces Round #427 (Div. 2) D. Palindromic characteristics(Manacher求回文串)

题目链接:Codeforces Round #427 (Div. 2) D. Palindromic characteristics 题意: 给你一个串,定义k-th回文串,让你求每个k-th的数量. 题解: manacher处理好后做一下dp就行了. 当然也可以直接dp不用manacher. 1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;++i) 3 using namespace std; 4 5 cons

Uva 10617 Again Palindrome (DP+回文串)

Problem I Again Palindromes Input: Standard Input Output: Standard Output Time Limit: 2 Seconds A palindorme is a sequence of one or more characters that reads the same from the left as it does from the right. For example, Z, TOT and MADAM are palind

[数位dp] lightoj 1205 Palindromic Numbers

题意:给定范围内是回文数的个数. 思路: dp[site][len]  site位的回文长度是len. 需要一个负责数组 ok存每位放的数. 然后就是dfs了,就是取len 的中间值mid 超过mid的话 就看看ok里面之前对称的那个数 判断是否相等 相等才能放进入下一位. 注意判断前导0,和这个oj必须用long long. 代码: #include"cstdlib" #include"cstdio" #include"cstring" #in

Lightoj1205——Palindromic Numbers(数位dp+回文数)

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

[LeetCode] Longest Palindromic Substring 最长回文串

Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring. http://fisherlei.blogspot.com/2012/12/leetcode-longest-palindromic-substrin