HDU 6156 回文 数位DP(2017CCPC)

Palindrome Function

Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 256000/256000 K (Java/Others)
Total Submission(s): 559    Accepted Submission(s): 299

Problem Description

As we all know,a palindrome number is the number which reads the same backward as forward,such as 666 or 747.Some numbers are not the palindrome numbers in decimal form,but in other base,they may become the palindrome number.Like 288,it’s not a palindrome number under 10-base.But if we convert it to 17-base number,it’s GG,which becomes a palindrome number.So we define an interesting function f(n,k) as follow:
f(n,k)=k if n is a palindrome number under k-base.
Otherwise f(n,k)=1.
Now given you 4 integers L,R,l,r,you need to caluclate the mathematics expression ∑Ri=L∑rj=lf(i,j) .
When representing the k-base(k>10) number,we need to use A to represent 10,B to represent 11,C to repesent 12 and so on.The biggest number is Z(35),so we only discuss about the situation at most 36-base number.

Input

The first line consists of an integer T,which denotes the number of test cases.
In the following T lines,each line consists of 4 integers L,R,l,r.
(1≤T≤105,1≤L≤R≤109,2≤l≤r≤36)

Output

For each test case, output the answer in the form of “Case #i: ans” in a seperate line.

Sample Input

3

1 1

2 36

1 982180

10 10

496690841 524639270

5 20

Sample Output

Case #1: 665

Case#2: 1000000

Case #3: 447525746

Source

2017中国大学生程序设计竞赛 - 网络选拔赛

思路:枚举进制计算结果即可。

代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 typedef long long LL;
 5 const int maxn = 1010;
 6 const int maxm = 55;
 7 const LL mod = 1e9+7;
 8 int digit[maxn], revert[maxn];
 9 LL L, R, l, r;
10 LL dp[maxm][maxm][maxn][2];
11
12 LL dfs(int k, int s, int l, bool ok, bool lim) {
13     if(l < 0) {
14         if(ok) return k;
15         return 1;
16     }
17     if(!lim && ~dp[k][s][l][ok]) return dp[k][s][l][ok];
18     int pos = lim ? digit[l] : k - 1;
19     LL ret = 0;
20     for(int i = 0; i <= pos; i++) {
21         revert[l] = i;
22         if(i == 0 && s == l) {
23             ret += dfs(k, s-1, l-1, ok, lim&&(i==pos));
24         }
25         else if(ok && l < (s + 1) / 2) {
26             ret += dfs(k, s, l-1, i==revert[s-l], lim&&(i==pos));
27         }
28         else {
29             ret += dfs(k, s, l-1, ok, lim&&(i==pos));
30         }
31     }
32     if(!lim) dp[k][s][l][ok] = ret;
33     return ret;
34 }
35
36 LL f(LL n, LL k) {
37     if(n == 0) return k;
38     int pos = 0;
39     while(n) {
40         digit[pos++] = n % k;
41         n /= k;
42     }
43     return dfs(k, pos-1, pos-1, 1, 1);
44 }
45
46
47 signed main() {
48     int T, tt = 1;
49     scanf("%d", &T);
50     memset(dp, -1, sizeof(dp));
51     while(T--) {
52         scanf("%lld%lld%lld%lld",&L,&R,&l,&r);
53         LL ret = 0;
54         for(int i = l; i <= r; i++) {
55             ret += f(R, i) - f(L-1, i);
56         }
57         printf("Case #%d: %lld\n", tt++, ret);
58     }
59     return 0;
60 }
时间: 2024-12-29 23:57:38

HDU 6156 回文 数位DP(2017CCPC)的相关文章

hdu 6156 Palindrome Function(回文数位dp)

题目链接:hdu 6156 Palindrome Function 题意: 给你一个L,R,l,r,问你在[L,R]内在[l,r]进制下有多少数是回文数,然后算一算贡献. 题解: 由于答案和该回文数的最高位有关(因为前导0不算). 考虑dp[i][j][k],表示在i进制下,当前考虑到第j位,该数字的起始点在第k位. 然后开一个数组记录一下前面的数字,做一下记忆化搜索就行了. 1 #include<bits/stdc++.h> 2 #define mst(a,b) memset(a,b,siz

HDU 6156 Palindrome Function 数位DP

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=6156 题目描述: 求L~R所有的数的l~r进制的f(x), f(x) = 当前进制 如果回文串, f(x) = 1 其他情况 解题思路: 数位DP, 统计个数 , 需要作出改变的就是进制和回文 代码: #include <iostream> #include <cstdio> #include <string> #include <vector> #inclu

hdu 3555 Bomb(数位dp)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3555 题目大意:就是给你一个数n,判断从0到n有多少个数含有数字49...... 是不是觉得跟hdu2089很相似呀... 思路:跟hdu2089一样的,注意给出的数比较大,所以这儿用__int64  .... code: #include<cstdio> #include<iostream> #include<cstring> #include<algorithm&

[ACM] hdu 2089 不要62(数位Dp)

不要62 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 19043    Accepted Submission(s): 6442 Problem Description 杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer). 杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就

HDU 2089 不要62(数位DP,三种姿势)

HDU 2089 不要62(数位DP,三种姿势) ACM 题目地址:HDU 2089 题意: 中文题意,不解释. 分析: 100w的数据,暴力打表能过 先初始化dp数组,表示前i位的三种情况,再进行推算 直接dfs,一遍搜一变记录,可能有不饥渴的全部算和饥渴的部分算情况,记录只能记录全部算(推荐看∑大的详细题解Orz) 代码: 1. 暴力 (以前写的) /* * Author: illuz <iilluzen[at]gmail.com> * File: 2089_bf.cpp * Create

HDU - 3555 Bomb (数位DP)

题意:求1-n里有多少人包含"49"的数字 思路:数位DP,分三种情况:到第i位没有49的情况,到第i位没有49且最高位是9的情况,到第i位有49的情况,将三种情况都考虑进去就是了 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; long long dp[30][3], n; int arr

HDU 4518 ac自动机+数位dp

吉哥系列故事--最终数 Time Limit: 500/200 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total Submission(s): 304    Accepted Submission(s): 102 Problem Description 在2012年腾讯编程马拉松比赛中,吉哥解决了一道关于斐波那契的题目,这让他非常高兴,也更加燃起了它对数学特别是斐波那契数的热爱.现在,它又在思考一个关于斐波那契

HDU Word Index (数位DP)

题意:给你字符串,算出它的数值: a -> 1 b -> 2 . . z -> 26 ab -> 27 ac -> 28 . . az -> 51 bc -> 52 . . vwxyz -> 83681 字母要求递增. #include<cstdio> #include<stdlib.h> #include<string.h> #include<string> #include<map> #incl

HDU 4722 Good Numbers (数位dp)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4722 思路:数位dp,dp[i][j]表示到第i位,数字和%10为j,然后进行dp,注意完全匹配的情况是要+1,而其他情况是从0 到 9 都要考虑 代码: #include <stdio.h> #include <string.h> #include <algorithm> #include <iostream> using namespace std; int