Cod sursa(job #1997953)

Utilizator laurageorgescuLaura Georgescu laurageorgescu Data 5 iulie 2017 22:56:17
Problema Bile2 Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.2 kb
#include <fstream>
#include <vector>
#include <iomanip>
#include <cassert>
#include <string>

using namespace std;

ifstream fin ("bile2.in"); ofstream fout ("bile2.out");

typedef vector< int > huge;

const int nmax = 1000;
const int base = 1e8;

huge fact[nmax + 1];
huge d[nmax + 1][nmax + 1];

huge operator + (const huge &x, const huge &y) {
    int t = 0;
    huge z = x;

    for (int i = 0; i < (int)y.size() || t != 0; ++ i) {
        if (i == (int)z.size()) {
            z.push_back( 0 );
        }
        if (i < (int)y.size()) {
            t += y[ i ];
        }
        t += z[ i ];
        z[ i ] = t % base;
        t /= base;
    }
    return z;
}

huge operator - (const huge &x, const huge &y) {
    int t = 0;
    huge z = x;

    for (int i = 0; i < (int)y.size() || t != 0; ++ i) {
        if (i < (int)y.size())
            t -= y[ i ];
        t += z[ i ];

        if (t < 0) {
            z[ i ] = t + base;
            t = -1;
        } else {
            z[ i ] = t;
            t = 0;
        }
    }

    while (!z.empty() && z.back() == 0) z.pop_back();
    return z;
}

huge operator * (const huge &x, const huge &y) {
    long long t = 0;
    huge z;
    z.resize((int)x.size() + (int)y.size() - 1);

    for (int i = 0; i < (int)x.size(); ++ i) {
        t = 0;
        for (int j = 0; j < (int)y.size() || t != 0; ++ j) {
            if (i + j == (int)z.size()) z.push_back( 0 );

            t += z[i + j] + 1LL * x[ i ] * y[ j ];
            z[i + j] = t % base;
            t /= base;
        }
    }

    while (!z.empty() && z.back() == 0) z.pop_back();
    return z;
}

huge nr (long long x) {
    huge z;
    while (x > 0) {
        z.push_back(x % base);
        x /= base;
    }
    return z;
}

bool operator <= (const huge &x, const huge &y) {
    if (x.size() != y.size()) {
        return x.size() < y.size();
    }
    assert(x.back() > 0 && y.back() > 0);

    int i = (int)x.size() - 1;
    while (i > 0 && x[ i ] == y[ i ]) -- i;
    return (x[ i ] <= y[ i ]);
}

void read (huge &x) {
    string s;
    fin >> s;

    int p = 1, r = 0;
    for (int i = (int)s.size() - 1; i >= 0; -- i) {
        r += p * (s[ i ] - '0');
        p *= 10;
        if (p == base) {
            p = 1;
            x.push_back( r );
            r = 0;
        }
    }

    if (r) x.push_back( r );
}

void afis (huge x) {
    fout << x.back();
    for (int i = (int)x.size() - 2;  i >= 0; -- i) {
        fout << setfill('0') << setw(4) << x[ i ];
    }
    fout << "\n";
}

int main() {
    int n, k; huge a, b;
    fin >> n >> k;
    read( a ); read( b );
    ++ k;

    for (int i = 1; i <= n; ++ i) {
        d[ 1 ][ i ].push_back( 1 );
        d[ 1 ][ i ] = d[ 1 ][ i ] + d[ 1 ][i - 1];
    }

    for (int i = 2; i <= n; ++ i) {
        for (int j = k; j <= n; ++ j) {
            d[ i ][ j ] = d[ i ][j - 1] + d[i - 1][j - k];
        }
    }

    fact[ 0 ].push_back( 1 );
    for (int i = 1; i <= n; ++ i) {
        fact[ i ] = fact[i - 1] * nr( i );
    }

    int ans = -1;

    huge ba = fact[ n ] * (b - a);
    for (int i = 1; i <= n; ++ i) {
        if (d[ i ][ n ] * fact[ i ] * fact[n - i] * b <= ba) {
            ans = i; break;
        }
    }

    fout << ans << "\n";

    fin.close();
    fout.close();
    return 0;
}