Leetcode-1015 Numbers With Repeated Digits(至少有 1 位重复的数字)

很典型的数位dp,把全球第一的代码拿过来研究了一下,加了点注释 

代码作者:waakaaka 

个人主页:https://leetcode.com/waakaaka/

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define db(x) cerr << #x << "=" << x << endl
 4 #define db2(x, y) cerr << #x << "=" << x << "," << #y << "=" << y << endl
 5 #define db3(x, y, z) cerr << #x << "=" << x << "," << #y << "=" << y << "," << #z << "=" << z << endl
 6 #define dbv(v) cerr << #v << "="; for (auto _x : v) cerr << _x << ", "; cerr << endl
 7 #define dba(a, n) cerr << #a << "="; for (int _i = 0; _i < (n); ++_i) cerr << a[_i] << ", "; cerr << endl
 8 typedef long long ll;
 9 typedef long double ld;
10 class Solution
11 {
12     public:
13         int n;
14         int dis;
15         //val为当前数值,bs可以看作是vector<int> hash(10)
16         void go(ll val, int bs)
17         {
18             // 当前数值小于题目所给n,非重复的结果数++
19             if (val <= n) ++dis;
20             //当前数值乘以10大于所给n,直接返回,不然进了下面的循环就乘以10继续递归了
21             if (val * 10 > n) return;
22             for (int i = 0; i <= 9; ++i)
23             {
24                 //当前数值为0(bs为零等价于val为零)且加的一个数字还是零,就直接continue,因为不支持前缀零
25                 if (!bs && i == 0) continue; // no 0 for first digit
26                 //如果要加的数字i和已经有的数字重复,就也continue,不进行递归 
27                 if (bs & (1 << i)) continue;
28                 //加上尾数i,然后更新状态bs,继续递归 
29                 go(val * 10 + i, bs | (1 << i));
30             }
31         }
32         int numDupDigitsAtMostN(int N)
33         {
34             dis = 0;
35             n = N;
36             go(0, 0);
37             //dis为不重复的数字的个数 
38             return N + 1 - dis;
39         }
40 };

 

posted @ 2019-03-17 21:03  Asurudo  阅读(571)  评论(0编辑  收藏  举报