beautiful number
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 883 Accepted Submission(s): 571
Problem Description
Let
A=∑ni=1ai∗10n−i(1≤ai≤9)
(
n
is the number of
A
's digits). We call
A
as “beautiful number” if and only if
a[i]≥a[i+1]
when
1≤i<n
and
a[i]
mod
a[j]=0
when
1≤i≤n,i<j≤n
(Such as 931 is a "beautiful number" while 87 isn't).
Could you tell me the number of “beautiful number” in the interval [L,R] (including L and R)?
Could you tell me the number of “beautiful number” in the interval [L,R] (including L and R)?
Input
The fist line contains a single integer
T
(about 100), indicating the number of cases.
Each test case begins with two integers L,R(1≤L≤R≤109) .
Each test case begins with two integers L,R(1≤L≤R≤109) .
Output
For each case, output an integer means the number of “beautiful number”.
Sample Input
2 1 11 999999993 999999999
Sample Output
10 2
//题意:
给一个数A,a[i]表示它 i 位上的数字,若a[i]>=a[i+1] (1<=i<n)且a[i] % a[j]==0(1<=i<j<=n),我们称数A为beautiful number。现在给你L,R,求[L,R]上beautiful number的个数。
//思路:
简单的数位DP+记忆化搜索:
定义一个二位DP数组:dp[i][j] : i 表示数位,j 表示该位前一位数字的值。
设第 i 位的值为num,它前一位的值为front,那么若满足front%num==0说明到目前为止是可行的,否则的话有这个前缀的所有数都不满足要求。(如果front<num,那么front%num的值必不可能==0);
此外,只有首位能取0,即若该数位前面的数位有非0值,那么此位及它后面的数位的值一定不能取0。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;
int cnt;
int bit[20];
int dp[20][20];
int dfs(int pos, int front, int mod, int flag)
{
if (pos <= 0)
return (mod == 0);
if (!flag&&dp[pos][front] != -1)
return dp[pos][front];
int num = flag ? bit[pos] : 9;
int ans = 0;
for (int i = 0; i <= num; i++)
{
if (i == 0 && pos < cnt&&front != 0)
continue;
else if (pos == cnt || front == 0)
{
//0不能取
if (i == 0 && pos == 1)
{
mod = 1;
continue;
}
else
mod = 0;
}
else
{
if (front%i == 0)
mod = 0;
else
{
mod = 1;
continue;
}
}
ans += dfs(pos - 1, i, mod, flag&&i == num);
}
if (!flag)
dp[pos][front] = ans;
return ans;
}
int solve(int num)
{
cnt = 0;
memset(bit, 0, sizeof(bit));
while (num)
{
bit[++cnt] = num % 10;
num = num / 10;
}
int ans;
if (cnt == 0)
ans = 0;
else
ans = dfs(cnt, 10, 0, 1);
return ans;
}
int main()
{
int T;
scanf("%d", &T);
memset(dp, -1, sizeof(dp));
while (T--)
{
int l, r;
scanf("%d%d", &l, &r);
int ans1 = solve(r);
int ans2 = solve(l - 1);
printf("%d\n", ans1 - ans2);
}
return 0;
}