Cod sursa(job #2820220)

Utilizator luiz_felipeLuiz Felipe luiz_felipe Data 20 decembrie 2021 02:54:13
Problema Numere 2 Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.09 kb
#include <fstream>
#include <cctype>
#include <cstring>

using namespace std;
int nr[128], baza = 4, t[128], mini[128], mid[128], maxi[128], k = 10000, c[128];

inline int maxim(int p, int q) {
    return (p > q) ? p : q;
}

class Huge {
public:
    int compare(const int *a, const int *b);

    void add(int *dest, const int *a, const int *b);

    void div(int *a);

    void mul(int *a, const int *b);
};

int Huge::compare(const int *a, const int *b) {
    if (a[0] > b[0]) return 1;
    if (a[0] < b[0]) return -1;
    for (int i = a[0]; i; --i)
        if (a[i] > b[i]) return 1;
        else if (a[i] < b[i]) return -1;
    return 0;
}

void Huge::add(int *dest, const int *a, const int *b) {
    int i;
    int tr = 0;
    for (i = 1, tr = 0; (i <= a[0]) || (i <= b[0]) || tr; ++i, tr /= k) dest[i] = (tr += a[i] + b[i]) % k;
    dest[0] = i - 1;
}

void Huge::div(int *a) {
    int i, temp;
    i = temp = a[0];
    while (i-- > 0) {
        if (a[i] % 2) a[i - 1] += k;
        a[i] /= 2;
    }
    a[0] = (a[temp]) ? temp : (temp - 1);
}

void Huge::mul(int *a, const int *b) {
    int i, j, tr;
    memset(reinterpret_cast<wchar_t *>(c), 0, sizeof(c));
    for (i = 0; i <= a[0]; ++i) {
        for (tr = 0, j = 1; j <= b[0] || tr; ++j, tr /= k) c[i + j - 1] = (tr += c[i + j - 1] + a[i] * b[j]) % k;
        c[0] = maxim(c[0], i + j - 2);
    }
    memcpy(a, c, sizeof(c));
}


int main() {
    ifstream f("numere2.in");
    ofstream g("numere2.out");
    Huge h;
    char c;
    bool OK = false;
    int i, j, crt;
    while (f >> c) {
        if (isdigit(c)) t[++t[0]] = c - '0';
    }
    for (i = t[0]; i > 0; i -= 4) {
        ++nr[0];
        for (crt = 1, j = 0; j <= 3 && (i - j) > 0; ++j, crt *= 10) nr[nr[0]] += crt * t[i - j];
    }
    for (i = 100; i > 1 && !OK; --i) {
        mini[0] = 1;
        maxi[0] = nr[0];
        for (j = 1; j <= nr[0]; ++j) maxi[j] = nr[j];
        while (h.compare(maxi, mini) > 0 && !OK) {
            memset(t, 0, sizeof(t));
            h.add(mid, mini, maxi);
            h.div(mid);
            t[0] = t[1] = 1;
            for (j = 1; j <= i && h.compare(nr, t) > 0; ++j) h.mul(t, mid);
            if (!h.compare(nr, t)) {
                g << mid[mid[0]];
                for (j = mid[0] - 1; j > 0; --j) g << mid[j];
                g << '\n' << i << '\n';
                OK = true;
                break;
            } else if (h.compare(nr, t) > 0) {
                crt = 1;
                memcpy(mini, mid, sizeof(mid));
                ++mini[1];
                while (mini[crt] == 10000) {
                    mini[crt++] = 0;
                    ++mini[crt];
                }
                mini[0] = maxim(mini[0], crt);
            } else {
                crt = 1;
                memcpy(maxi, mid, sizeof(mid));
                --maxi[1];
                while (maxi[crt] == -1) {
                    maxi[crt++] = 9999;
                    --maxi[crt];
                }
                if (!maxi[maxi[0]]) --maxi[0];
            }
        }
    }
    if (!OK) {
        g << nr[nr[0]];
        for (i = nr[0] - 1; i > 0; --i) g << nr[i];
        printf("\n1\n");
    }
    return 0;
}