beautiful number
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 951 Accepted Submission(s): 610
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
题意:应该不难懂吧,很简短。。
题解:简单的数位dp。对于当前位若为loc,若loc为0,则下一位可以枚举任意数字,否则下一位只能枚举1到上界(无限制时上界为9)满足loc % i == 0的i可以往下搜索。非常的简单~
AC代码
#include <stdio.h>
#include <iostream>
#include <string>
#include <queue>
#include <map>
#include <vector>
#include <algorithm>
#include <string.h>
#include <cmath>
using namespace std;
const int maxn = 11;
int dp[maxn][maxn], a[maxn];
int dfs(int len, int limit, int loc){
if(len == -1)
return (loc != 0);
if(!limit && dp[len][loc] != -1)
return dp[len][loc];
int ans = 0, max1 = (limit ? a[len] : 9);
for(int i = (loc ? 1 : 0); i <= max1; i++){
if(loc == 0 || loc % i == 0)
ans += dfs(len - 1, limit && (i == max1), i);
}
if(!limit)
dp[len][loc] = ans;
return ans;
}
int solve(int n){
if(!n)
return 0;
int pos = 0;
while(n){
a[pos++] = (n % 10);
n /= 10;
}
pos--;
int ans = 0;
for(int i = 0; i <= a[pos]; i++)
ans += dfs(pos - 1, i == a[pos], i);
return ans;
}
int main(){
memset(dp, -1, sizeof(dp));
int t, l, r;
scanf("%d", &t);
while(t--){
scanf("%d %d", &l, &r);
printf("%d\n", solve(r) - solve(l - 1));
}
return 0;
}