Beautiful Numbers(牛客)

时间:2019-06-13
本文章向大家介绍Beautiful Numbers(牛客),主要包括Beautiful Numbers(牛客)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

链接:https://ac.nowcoder.com/acm/problem/17385
来源:牛客网

题目描述

NIBGNAUK is an odd boy and his taste is strange as well. It seems to him that a positive integer number is beautiful if and only if it is divisible by the sum of its digits.
We will not argue with this and just count the quantity of beautiful numbers from 1 to N.

输入描述:

The first line of the input is T(1≤ T ≤ 100), which stands for the number of test cases you need to solve.
Each test case contains a line with a positive integer N (1 ≤ N ≤ 10^12).

输出描述:

For each test case, print the case number and the quantity of beautiful numbers in [1, N].

具体思路:

之前做过的这类题是模数是固定的,然后再去求这段区间有多少满足的。但是对于这个题,因为模数是变化的,所以我们就需要想一个可以固定模数的方法。因为只有12位,所以这个模数的总的情况就是9*12=108.我们就可以通过枚举模数来进行找答案;还需要考虑去重的因素,每一次枚举模数,看哪些数的位数之和能凑出当前的模数,然后检验的时候就按照正常固定模数的方法打就可以了。

AC代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 2e6+20;
 4 # define ll long long
 5 # define inf 0x3f3f3f3f
 6 int mod;
 7 int a[15];
 8 ll dp[15][120][120];
 9 ll dfs(int pos,int sum,int left,bool is_head)
10 {
11     if(!pos)
12         return sum==mod&&left==0;
13     if(!is_head&&dp[pos][sum][left]!=-1)
14         return dp[pos][sum][left];
15     ll ans=0;
16     int fmax = is_head ? a[pos] : 9;
17     for(int i=0; i<=fmax; i++)
18     {
19         if(sum+i>mod)
20             break;
21         ans+=dfs(pos-1,sum+i,(left*10+i)%mod,is_head&&i==fmax);
22     }
23     if(!is_head)
24         dp[pos][sum][left]=ans;
25     return ans;
26 }
27 ll solve(ll n)
28 {
29     int num=0;
30     int sum=0;
31     while(n)
32     {
33         a[++num]=n%10;
34         sum+=a[num];
35         n/=10;
36     }
37     ll ans=0;
38     int tmp=9*num;
39     for(int i=1; i<=tmp; i++)
40     {
41         memset(dp,-1,sizeof(dp));
42         mod=i;
43         ans+=dfs(num,0,0,1);
44     }
45     return ans;
46 }
47 int main()
48 {
49     int T,Case=0;
50     scanf("%d",&T);
51     while(T--)
52     {
53         ll n;
54         scanf("%lld",&n);
55         printf("Case %d: %lld\n",++Case,solve(n));
56     }
57     return 0;
58 }

原文地址:https://www.cnblogs.com/letlifestop/p/11014023.html