zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    今日SGU 5.2
    奇异值分解(SVD)小结
    计蒜客16495 Truefriend(fwt)
    计蒜客16492 building(二分线段树/分块)
    hihocoder 1323 回文字符串(字符串+dp)
    hihocoder 1320 压缩字符串(字符串+dp)
    hdu6121 build a tree(树)
    hdu6103 Kirinriki(trick+字符串)
    hdu6097 Mindis(几何)
    hdu 6057 Kanade's convolution(子集卷积)
  • 原文地址:https://www.cnblogs.com/00isok/p/9612908.html
Copyright © 2011-2022 走看看