Here is a function f(x): int f ( int x ) { if ( x == 0 ) return 0; return f ( x / 10 ) + x % 10; }
Now, you want to know, in a given interval [A, B] (1 <= A <= B <= 10 9), how many integer x that mod f(x) equal to 0.
Each test case has two integers A, B.
2 1 10 11 20
Case 1: 10 Case 2: 3
题意:求l,r中满足题意的数的个数,这种数满足的条件是x%(该数的各位之和)==0
思路:
数位dp,dp[i][j][k][m],i表示的还是i位,j表示到目前为止各位之和,k表示到目前为止取模的结果,m表示枚举的整个数的各位之和
由于x<1e9,所以各位之和的范围为0~81,可以一一枚举
ac代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> using namespace std; int num[12]; int dp[12][85][85][85]; int dfs(int len,int sum,int mod,int tmp ,int f) { if(len<0) return sum==tmp&&mod==0; if(!f&&dp[len][sum][mod][tmp]!=-1) return dp[len][sum][mod][tmp]; int fp=f?num[len]:9; int ret=0; for(int i=0;i<=fp;i++) { ret+=dfs(len-1,sum+i,(mod*10+i)%tmp,tmp,f&&i==fp); } if(!f) dp[len][sum][mod][tmp]=ret; return ret; } int get_num(int x) { int len=0; while(x) { num[len++]=x%10; x=x/10; } int ans=0; for(int i=1;i<=81;i++) ans+=dfs(len-1,0,0,i,1); return ans; } int main() { int t; cin>>t; memset(dp,-1,sizeof(dp)); int p=0; while(t--) { p++; int a,b; cin>>a>>b; printf("Case %d: ",p); cout<<get_num(b)-get_num(a-1)<<endl; } return 0; }