Problema de conteo DP de estadísticas digitales

Portal de título original

Analizando

¡Ahhhhhhhh! Esta pregunta solo se resolvió por la tarde ¡Hay tantos problemas de límites!

Para los problemas que son más difíciles de resolver directamente, puede convertirlos en prefijos. Lo mismo ocurre con este problema. Puede resolver el número de apariciones del número x en 1 ~ b, restar el número de apariciones del número x en 1 ~ a-1, y obtener una respuesta indirecta

Suponga que un número se representa como abcdefg bit a bit, y el puntero apunta al bit d, y cuente las respuestas en este caso
Cuando x no es 0
1. Cuando el dígito de d enumera x, los tres dígitos de abc pueden oscilar entre 000 y abc-1, y los tres dígitos de efg pueden oscilar entre 000 y 999, que es 1000 = 10. 3 opciones.
2. Cuando el tres dígitos de abc Al enumerar abc, cuando d <x, hay 0 opciones
3. Cuando los tres dígitos de abc enumeran abc, cuando d = x, los tres dígitos de efg tienen 000 ~ efg, es decir, efg + 1 Opción
4. Cuando los tres dígitos de abc enumeran abc, cuando d> x, los tres dígitos de efg tienen 000 ~ 999, es decir, 1000 = 10 3 opciones
Cuando x es 0
Solo 1 es diferente de la situación anterior, porque cuando d es 0, no puede haber un 0 a la izquierda, por lo que los tres dígitos de abc solo se pueden seleccionar del rango de 001 a abc-1

Código

Habrá muchos problemas de límites en el código.
Cuando n == 0, el número de apariciones de x es 0.
Al contar el número de apariciones de 0 , el bit alto no puede ser 0

#include <bits/stdc++.h>
using namespace std;
int power10(int i)
{
    
    
    int res=1;
    while(i--) res*=10;
    return res;
}
int get(vector<int>vis,int l,int r)
{
    
    
    int res=0;
    for(int i=l;i>=r;i--) res=res*10+vis[i];
    return res;
}
int count(int n,int x) //1~n中数x出现的次数
{
    
    
    if(n==0) return 0; //处理边界
    vector<int>vis;
    while(n)
    {
    
    
        vis.push_back(n%10);
        n/=10;
    }
    int l=vis.size(); //记录这个数一共有多少位
    int res=0;
    for(int i=l-1-!x;i>=0;i--) //当x==0时因为最高位不能是0,因此从第二位开始枚举
    {
    
    
        if(i<l-1) //枚举到最高位的时候,不存在比这一位更高的位
        {
    
    
            res+=get(vis,l-1,i+1)*power10(i);
            if(!x) res-=power10(i); //当x==0时,高位的数要从001开始枚举
        }
        if(vis[i]==x) res+=get(vis,i-1,0)+1;
        else if(vis[i]>x) res+=power10(i);
    }
    return res;
    
}
int main()
{
    
    
    int a,b;
    while(cin>>a>>b&&a!=0&&b!=0)
    {
    
    
        if(a>b) swap(a,b);
        for(int i=0;i<10;i++)
            cout<<count(b,i)-count(a-1,i)<<" ";
        cout<<endl;
    }
    return 0;
}

Supongo que te gusta

Origin blog.csdn.net/qq_46126537/article/details/113091972
Recomendado
Clasificación