Educational Codeforces Round 50 (Rated for Div. 2) C. Classy Numbers
Posted yichuan-sun
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Educational Codeforces Round 50 (Rated for Div. 2) C. Classy Numbers相关的知识,希望对你有一定的参考价值。
看到数论就懵了,题目有两个解法,第一个解法是组合数学的内容,解析用英文写的,看不懂;第二个解法是暴力搜索的,找了网上用同样方法的中文注释代码才看明白。首先如果直接枚举肯定玩完,要找些其他办法。题目中用到了dfs,或者叫暴力搜索,但是思路很巧妙。函数设计了三个参数,分别是搜索层数lev,代表10的次方数;当前处理的数字cu,为了不越界,用long long型;非0位数的个数cnt。如果层数超过了18,就应该返回。设置一个vector,存long long型数据,每次如果没返回,就把这个数加进vector。之后用循环控制接下来的搜索过程。
代码如下。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
vector<ll> v;
void brute(int lev,ll cu,int cnt) {
if (lev==18) {
v.push_back(cu);
return;
}
brute(lev+1,cu*10,cnt);
if (cnt<3) {
for (int i=1;i<=9;i++)
brute(lev+1,cu*10+i,cnt+1);
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
brute(0,0,0);
v.push_back(1e18);
ll l,r;
int n;
cin>>n;
for (int i=0;i<n;i++) {
cin>>l>>r;
int ans=upper_bound(v.begin(),v.end(),r)-lower_bound(v.begin(),v.end(),l);
cout<<ans<<endl;
}
return 0;
}
貌似这样会有重复搜索的内容,可能会爆栈或TLE,但是每次搜索时的X10,会让这一分支不断加深,到最深后,两侧的递归树会不断伸展,直到覆盖整个10^18的所有数。这个搜索才18层,但是已经足以达到所有数字了,时间复杂度可以保证。
注意:
1.C++中的两个二分查找标准库函数:upper_bound(iterator begin,iterator end,elem)——从升序排列的顺序存储结构中寻找大于elem的第一个元素,返回指向这个元素的迭代器。如果未找到,返回指向elelm的迭代器
2.C++中的两个二分查找标准库函数:lower_bound(iterator begin,iterator end,elem)——从升序排列的顺序存储结构中寻找大于等于elem的第一个元素,返回指向这个元素的迭代器。如果未找到,返回指向elelm的迭代器
以上是关于Educational Codeforces Round 50 (Rated for Div. 2) C. Classy Numbers的主要内容,如果未能解决你的问题,请参考以下文章
Educational Codeforces Round 7 A
Educational Codeforces Round 7
Educational Codeforces Round 90
Educational Codeforces Round 33