Cod sursa(job #3214207)

Utilizator Horia_haivasHaivas Horia Horia_haivas Data 13 martie 2024 21:29:01
Problema Cifre Scor 80
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 6.24 kb
/*
    "care a facut teste cu Lattice reduction attack e ciudat"
    "linistiti va putin"
    - 2023 -
*/
#include<bits/stdc++.h>
#define debug(x) cerr << #x << " " << x << "\n"
#define debugs(x) cerr << #x << " " << x << " "
#pragma GCC optimize("Ofast")
#define int long long

using namespace std;

int dp[12][12][2];
int dplim[12][12][2];
int vlim[12];
int c,k;

void calcdplim0(int x) ///e gen calc doar ca imi fac fara limita (x asta e mereu mai mare ca b)
{
    int cnt,len,newcif,app,ans,legitsum,actual;
    cnt=0;
    do
    {
        cnt++;
        vlim[cnt]=x%10;
        x=x/10;
    }
    while (x);
    reverse(vlim+1,vlim+1+cnt);
    for (len=1; len<=cnt; len++)
    {
        for (app=0; app<=cnt; app++)
        {
            dplim[len][app][0]=0;
            dplim[len][app][1]=0;
        }
    }
    for (len=1; len<=cnt; len++)
    {
        if (len!=1)
        {
            for (app=0; app<=len; app++)
            {
                if (vlim[len]==c && app!=0)
                {
                    dplim[len][app][1]+=dplim[len-1][app-1][1];
                }
                else if (vlim[len]!=c)
                {
                    dplim[len][app][1]+=dplim[len-1][app][1];
                }
            }
            for (newcif=0; newcif<=9; newcif++)
            {
                for (app=0; app<=len; app++)
                {
                    if (newcif<vlim[len])
                    {
                        if (newcif==c && app!=0)
                        {
                            dplim[len][app][0]+=dplim[len-1][app-1][0];
                            dplim[len][app][0]+=dplim[len-1][app-1][1];
                        }
                        else if (newcif!=c)
                        {
                            dplim[len][app][0]+=dplim[len-1][app][0];
                            dplim[len][app][0]+=dplim[len-1][app][1];
                        }
                    }
                    else
                    {
                        if (newcif==c && app!=0)
                            dplim[len][app][0]+=dplim[len-1][app-1][0];
                        else if (newcif!=c)
                            dplim[len][app][0]+=dplim[len-1][app][0];
                    }
                }
            }
        }
        else
        {
            for(newcif=1; newcif<=9; newcif++)
            {
                if (newcif==vlim[len] && newcif==c)
                    dplim[len][1][1]=1;
                else if (newcif==vlim[len])
                    dplim[len][0][1]=1;
                else if (newcif==c && newcif<vlim[len])
                    dplim[len][1][0]=1;
                else if (newcif<vlim[len])
                    dplim[len][0][0]++;
            }
        }
    }
}

int calc(int x)
{
    int cnt,len,newcif,app,ans,i,j,actual;
    cnt=0;
    do
    {
        cnt++;
        vlim[cnt]=x%10;
        x=x/10;
    }
    while (x);
    reverse(vlim+1,vlim+1+cnt);
    for (len=1; len<=cnt; len++)
    {
        for (app=0; app<=cnt; app++)
        {
            dp[len][app][0]=0;
            dp[len][app][1]=0;
        }
    }
    for (len=1; len<=cnt; len++)
    {
        if (len!=1)
        {
            for (app=0; app<=len; app++)
            {
                if (vlim[len]==c && app!=0)
                {
                    dp[len][app][1]+=dp[len-1][app-1][1];
                }
                else if (vlim[len]!=c)
                {
                    dp[len][app][1]+=dp[len-1][app][1];
                }
            }
            for (newcif=0; newcif<=9; newcif++)
            {
                for (app=0; app<=len; app++)
                {
                    if (newcif<vlim[len])
                    {
                        if (newcif==c && app!=0)
                        {
                            dp[len][app][0]+=dp[len-1][app-1][0];
                            dp[len][app][0]+=dp[len-1][app-1][1];
                        }
                        else if (newcif!=c)
                        {
                            dp[len][app][0]+=dp[len-1][app][0];
                            dp[len][app][0]+=dp[len-1][app][1];
                        }
                    }
                    else
                    {
                        if (newcif==c && app!=0)
                            dp[len][app][0]+=dp[len-1][app-1][0];
                        else if (newcif!=c)
                            dp[len][app][0]+=dp[len-1][app][0];
                    }
                }
            }
        }
        else
        {
            for(newcif=0; newcif<=9; newcif++)
            {
                if (newcif==vlim[len] && newcif==c)
                    dp[len][1][1]=1;
                else if (newcif==vlim[len])
                    dp[len][0][1]=1;
                else if (newcif==c && newcif<vlim[len])
                    dp[len][1][0]=1;
                else if (newcif<vlim[len])
                    dp[len][0][0]++;
            }
        }
    }
    ans=0;
    if (c!=0)
    {
        for(app=k; app<=cnt; app++)
        {
            ans+=dp[cnt][app][0];
            ans+=dp[cnt][app][1];
        }
    }
    else
    {
        for (app=0; app<=cnt; app++)
        {
            actual=0;
            if (app!=0 && app!=cnt)
            {
                actual+=dp[cnt][app][0]+dp[cnt][app][1];
                for (i=1; i<=app; i++)
                {
                    actual-=dplim[cnt-i][app-i][0]+dplim[cnt-i][app-i][1];
                }
            }
            else if (app==0)
            {
                actual+=dp[cnt][app][0]+dp[cnt][app][1];
            }
            else
            {
                actual++;
            }
            if (app>=k)
                ans+=actual;
        }
    }
    return ans;
}

signed main()
{
    ifstream fin("cifre.in");
    ofstream fout("cifre.out");
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    long long a,b,favorabil,total;
    long double probabilitate;
    fin >> a >> b >> c >> k;
    if (c==0)
    {
        calcdplim0(999999999);
        if (k==9)
            assert(0);
    }
    if (a!=0)
    {
        favorabil=calc(b)-calc(a-1);
        total=b-a+1;
    }
    else
    {
        favorabil=calc(b);
        total=b+1;
    }
    ///to do : rezolv problema cu leading zeros
    probabilitate=1.0*favorabil/total;
    fout << fixed << setprecision(5) << probabilitate;
}