zoukankan      html  css  js  c++  java
  • UVa11361

     Investigating Div-Sum Property

    Aninteger is divisible by 3 if the sum of its digits is also divisible by 3. Forexample, 3702 is divisible by 3 and 12(3+7+0+2) is also divisible by 3. Thisproperty also holds for the integer 9.

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

    Input

    The first line of input is an integer T(T<100) thatindicates the number of test cases. Each case is a line containing 3 positiveintegers AB and K.1 <= A <= B < 2^31 and0<K<10000.

    Output

    For each case,output the number of integers in the range [AB] which is divisible by K and the sumof its digits is also divisible by K.

    Sample Input

    Output for Sample Input

    3

    1 20 1

    1 20 2

    1 1000 4

    20

    5

    64

    题意:

           给出正整数a、b、k,需要你统计在区间[a,b]内的整数有多少满足各位数字之和与数本身模k都为零。

    分析:

    设func(n)是不超过n的非负整数中满足条件的数的个数。答案就是func(b)-func(a-1)。

    于是我们希望求得func(n)。

    我们将不超过n的非负整数进行分段统计,比如将3212分解成这么几个区间:***(000~999),1***,2***,30**,31**,320*,3210,3211,3212。其中每一个区间都有一个固定的前缀以及若干的星号后缀(每一个星号表示该位的数字可以任意选择)。

    设状态dp[d][m1][m2]表示满足一共有d个数字(允许前导零),数字之和除以k余m1,数本身除以k余m2的数的个数。于是“22***”对应的解的个数就是dp[3][3][1](在模7的情况下)。

    状态转移方程就是:

    dp(d,m1,m2)=sum{dp(d-1,(m1-x)modk,(m2-x*10^(d-1))modk)|x=0,1,…,9}

    接下来就是对n分离数位,从低至高依次存储,然后从高到低枚举每一位的情况。

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <cstring>
     4 #include <string>
     5 #include <cstdio>
     6 using namespace std;
     7 int a,b,k; // 整数a与整数b之间,模k
     8 int dp[15][110][110]; //dp[i][j][l]表示一共i个未确定数字,满足所有数字之和modk余j、数字组成的整数modk余l的数的个数
     9 int pw[11] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
    10 // 记忆化搜索
    11 int dfs(int d,int m1,int m2){
    12     if(d == 0) return (m1 == 0 && m2 == 0) ? 1 : 0;
    13     if(dp[d][m1][m2] >= 0) return dp[d][m1][m2];
    14     dp[d][m1][m2] = 0;
    15     for(int i = 0 ; i < 10 ; i++) // 枚举9个数字
    16         dp[d][m1][m2] += dfs(d - 1,((m1 - i) % k + k) % k, ((m2 - i * pw[d - 1]) % k + k) % k);
    17     return dp[d][m1][m2];
    18 }
    19 int func(int n){ // 不超过n的满足条件的非负整数个数
    20     int d = 0,m1 = 0,m2 = 0,a[15];
    21     if(n == 0) a[d++] = 0;
    22     while(n != 0) // 分离数位
    23         a[d] = n % 10,n /= 10,d++;
    24     int ans = 0;
    25     for(int i = d - 1 ; i >= 0 ; i--){ // 从高位到低位
    26         if(i != 0)
    27         for(int j = 0 ; j < a[i] ; j++)
    28             ans += dfs(i,(k - (m1 + j) % k) % k,(k - (m2 + pw[i] * j) % k) % k);
    29         else
    30         for(int j = 0; j <= a[i] ; j++)
    31             ans += dfs(i,(k - (m1 + j) % k) % k,(k - (m2 + pw[i] * j) % k) % k);
    32         m1 += a[i],m2 += pw[i] * a[i]; // 已经确定的数
    33     }
    34     return ans;
    35 }
    36 
    37 int main(){
    38     int t; scanf("%d",&t);
    39     while(t--){
    40         scanf("%d%d%d",&a,&b,&k);
    41         if(k > 85) printf("0
    ");
    42         else{
    43             memset(dp,-1,sizeof(dp));
    44             printf("%d
    ",func(b) - func(a - 1));
    45         }
    46     }
    47     return 0;
    48 }
    View Code
  • 相关阅读:
    Oracle系列二 基本的SQL SELECT语句
    Oracle系列一 SQL语句基本概念和学习准备
    Android 动态更换桌面图标
    Linux_CentOS下搭建Nodejs 生产环境-以及nodejs进程管理器pm2的使用
    Linux_CentOS中Mongodb4.x 安装调试、远程管理、配置 mongodb 管理员密码
    Linux_CentOS 中systemctl 管理服务、防火墙 firewalld 以及 SELinux 配置
    Linux_CentOS 内存、cpu、进程、端口、硬盘管理
    Linux_CentOS中的MySQL 数据库的安装调试、远程管理
    LInux_CentosOS中yum安装jdk及配置环境变量
    Linux_CentOS软件安装调试 源代码包编译安装和 二进制包配置
  • 原文地址:https://www.cnblogs.com/cyb123456/p/5806064.html
Copyright © 2011-2022 走看看