Codeforces 1036C Classy Numbers 【DFS】

<题目链接>

题目大意:

对于那些各个位数上的非0数小于等于3的数,我们称为 classy number ,现在给你一个闭区间 [L,R]  (1≤L≤R≤1018).,问你这个区间内有多少个classy number 数。

解题分析:

对于这种对数的数位有要求的题目,可以往搜索,dp上想一想,本题可用搜索做。先用搜索将所有符合条件的数放入vector ,然后排序,再用二分函数得到 L,R的坐标,再相减,即可得到 [L,R]区间中满足条件的数的个数。

 

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

int T;
long long l, r;
vector<long long> v;

void dfs(int dep, long long res, int n) {    //dep记录递归的深度,即res的位数,n表示res数中!=0的数字个数
    v.push_back(res);
    if(dep==18) return;

    //下面分两种情况dfs
    dfs(dep+1,res*10,n);    //下一位仍然为0

    if(n<3){
        for(int i=1;i<=9;++i)
            dfs(dep+1,res*10+i,n+1);     //下一位不为0
    }
}

int main() {
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);     //可以通过tie(0)(0表示NULL)来解除cin与cout的绑定,进一步加快执行效率
    cin >> T;
    for(int i=1;i<=9;++i)   dfs(1,i,1);     //按首位为i的数字向下进行递归
    //上面的预处理将所有18位及其一下的所有 符合条件的数全部加入vector 

    v.push_back(1e18);   //注意1e18有19位,所以要将1e18单独加入 vector
    sort(v.begin(), v.end());
    while(T--) {
        cin >> l >> r;
        cout << upper_bound(v.begin(),v.end(),r)-lower_bound(v.begin(),v.end(),l) << endl;
        //因为这是闭区间,所以一个用upper_bound,一个用lower_bound
    }
    return 0;
}

 

posted @ 2018-09-09 11:03  悠悠呦~  阅读(422)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end