数码

数码

https://ac.nowcoder.com/acm/problem/13221

题目描述

给定两个整数 l 和 r ,对于所有满足1 ≤ l ≤ x ≤ r ≤ 10^9 的 x ,把 x 的所有约数全部写下来。对于每个写下来的数,只保留最高位的那个数码。求1~9每个数码出现的次数。

思路

我们设定一个函数calc(x)可以计算1-x中1-9每个数码出现的次数,那么我们只需计算两次,分别是calc(r)和calc(l-1)然后相减就行
那么我们如何计算设计calc函数呢?
那么我们要计算最高位为1-9肯定是要循环1-9,我这里就举例如何计算最高位为1的,其他位类似。
我们先预处理一个数组存每一位的最小非0数
即1位数最小是1, 2位数最小是10……
下面对于不同的位数我们有两个思路,现在我们以2位数为例
方法1:
2位数1开头的分别是10-19,那么我们枚举10-19,for(int i=10;i<=19;i++)
那么x/i就是1-x中含有i的因数的数的个数,这个很好理解
方法2:
我们让x去除以2位数开头最小的数,我们假设他为_ed,然后我们循环1-_ed,for(int i=1;i<=_ed;i++),现在我们和上面的思路不一样,我们求10-19中每一个数乘以i的数在x范围内的个数。

我们会发现方法1在位数较少时效率较高,方法2在位数较多时效率较高,他们是互补的,那么我们就运用分块的思想,当位数少时用方法一,位数多时用方法二。
复杂度
#代码

//#pragma GCC optimize(2)
#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f3f;
vector<ll> v;
ll *ans;
ll *ans2;
ll l,r;

void pre()
{
    ll tmp=1;
    for(int i=0;i<10;i++)
    {
        v.push_back(tmp);
        tmp*=10;
    }
}

ll* calc(ll x)
{
    ll *ans=new ll[10];
    for(int i=0;i<10;i++)
        ans[i]=0; 
    for(int num=1;num<=9;num++)
    {
        //枚举位数
        for(auto i:v)
        {
            if(i<=100000)
            {
                //方法一
                ll st=i*num;
                ll ed=st+i-1;
                if(st>x)
                    break;
                for(ll j=st;j<=ed;j++)
                {
                    ans[num]+=x/j;
                }
            }
            else
            {
                //方法二
                ll st=i*num;
                ll ed=st+i-1;
                if(st>x)
                    break;
                ll _ed=x/st;
                for(int j=1;j<=_ed;j++)
                {
                    ll a=x-st*j;
                    ans[num]+=min(a/j+1,ed-st+1);
                }
            }
        }    
    }
    return ans;    
}

int main()
{
    ios::sync_with_stdio(false);
    cin>>l>>r;
    pre();
    ans2=calc(r);
    ans=calc(l-1);
    for(int i=1;i<=9;i++)
        cout<<ans2[i]-ans[i]<<endl;    
     return 0;
}

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务