Lightoj 1068 数位dp

来源:互联网 发布:淘宝绫致时装官方店 编辑:程序博客网 时间:2024/06/10 18:45
Investigation
Time Limit: 2000MS Memory Limit: 32768KB 64bit IO Format: %lld & %llu


Description

An integer is divisible by 3 if the sum of its digits is also divisible by 3. For example, 3702 is divisible by 3 and 12 (3+7+0+2) is also divisible by 3. This property also holds for the integer 9.

In this problem, we will investigate this property for other integers.

Input

Input starts with an integer T (≤ 200), denoting the number of test cases.

Each case contains three positive integers A, B and K (1 ≤ A ≤ B < 231 and 0 < K < 10000).

Output

For each case, output the case number and the number of integers in the range [A, B] which are divisible by K and the sum of its digits is also divisible byK.

Sample Input

3

1 20 1

1 20 2

1 1000 4

Sample Output

Case 1: 20

Case 2: 5

Case 3: 64


题意:a和b,求出a和b区间能被k整除且它各个位的和也能被k整除的数的个数。

题解:数位dp。

#include <stdio.h>  #include <string.h>  #include <algorithm>  using namespace std;  typedef long long ll;ll bit[15];  ll dp[10][123][105][2],k;  ll dfs(ll pos,ll mod,ll have,ll lim){      ll num,i,ans,mod_x,have_x;      if(pos<=0)          return mod%k==0&&have%k==0;      if(!lim&&dp[pos][mod][have][lim]!=-1)        return dp[pos][mod][have][lim];      num=lim?bit[pos]:9;    ans=0;      for(i=0;i<=num;i++){          ans+=dfs(pos-1,mod+i,(have*10+i)%k,lim&&i==num);    }      if(!lim)          dp[pos][mod][have][lim]=ans;      return ans;  }    int main(){      ll n,len,t,m,cas=1,i;scanf("%lld",&t);     while(t--){          len=0;        scanf("%lld%lld%lld",&n,&m,&k);if(k>=100){printf("Case %lld: %lld\n",cas++,0);continue;} memset(dp,-1,sizeof(dp));        memset(bit,0,sizeof(bit));   n--;        while(n){              bit[++len]=n%10;              n/=10;          }          ll sol1=dfs(len,0,0,1);        len=0;while(m){bit[++len]=m%10;m/=10;}ll sol2=dfs(len,0,0,1);printf("Case %lld: %lld\n",cas++,sol2-sol1);    }      return 0;  }  


0 0
原创粉丝点击