Cod sursa(job #1768792)

Utilizator alittlezzCazaciuc Valentin alittlezz Data 1 octombrie 2016 14:16:33
Problema Numere 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.13 kb
#include <fstream>
#include <algorithm>
#include <cstring>

using namespace std;

const int N = 300;
int P[N], lf[N], rg[N], md[N], base[N], sol[N], tmp[N];
char buffer[105];

void initBinarySearch(int b){
    rg[0] = ceil((double)(P[0]+1)/b) + 1;
    lf[0] = max(rg[0]-3, 0);
    lf[lf[0]] = 1;
    for(int i = 1;i < rg[0];i++){
        rg[i] = 0;
    }
    rg[rg[0]] = 1;
}

void calculateMiddle(){
    int i;
    int T = 0;
    md[0] = rg[0];
    for(i = 1;i <= md[0];i++){
        md[i] = rg[i] + lf[i] + T;
        T = md[i]/10;
        md[i] %= 10;
    }
    if(T){
        md[++md[0]] = T;
    }
    T = 0;
    for(i = md[0];i >= 1;i--){
        T = 10*T + md[i];
        md[i] = T/2;
        T %= 2;
    }
    if(md[md[0]] == 0 && md[0] > 1){
        md[0]--;
    }
}

void calculateRg(){
    int i,T;
    for(i = 0;i <= md[0];i++){
        rg[i] = md[i];
    }
    T = 1;
    for(i = 1;i <= rg[0];i++){
        rg[i] -= T;
        if(rg[i] < 0){
            rg[i] += 10;
            T = 1;
        }else{
            T = 0;
        }
    }
    while(rg[rg[0]] == 0 && rg[0] > 1){
        rg[0]--;
    }
}

void calculateLf(){
    int i,T;
    for(i = 0;i <= md[0];i++){
        lf[i] = md[i];
    }
    T = 1;
    for(i = 1;i <= lf[0];i++){
        lf[i] += T;
        T = lf[i]/10;
        lf[i] %= 10;
    }
    if(T){
        lf[++lf[0]] = T;
    }
}

void calculateSol(){
    int i,j;
    tmp[0] = sol[0] + base[0] - 1;
    for(i = 1;i <= tmp[0];i++){
        tmp[i] = 0;
    }
    for(i = 1;i <= sol[0];i++){
        for(j = 1;j <= base[0];j++){
            tmp[i + j - 1] += sol[i] * base[j];
        }
    }
    int T = 0;
    for(i = 1;i <= tmp[0];i++){
        tmp[i] += T;
        T = tmp[i] / 10;
        tmp[i] %= 10;
    }
    if(T){
        tmp[++tmp[0]] = T;
    }
    for(i = 0;i <= tmp[0];i++){
        sol[i] = tmp[i];
    }
}

void calculateBase(){
    int i,j;
    tmp[0] = base[0] + base[0] - 1;
    for(i = 1;i <= tmp[0];i++){
        tmp[i] = 0;
    }
    for(i = 1;i <= base[0];i++){
        for(j = 1;j <= base[0];j++){
            tmp[i + j - 1] += base[i] * base[j];
        }
    }
    int T = 0;
    for(i = 1;i <= tmp[0];i++){
        tmp[i] += T;
        T = tmp[i] / 10;
        tmp[i] %= 10;
    }
    if(T){
        tmp[++tmp[0]] = T;
    }
    for(i = 0;i <= tmp[0];i++){
        base[i] = tmp[i];
    }
}

int areEqual(int e){
    sol[0] = sol[1] = 1;
    int i;
    for(i = 0;i <= md[0];i++){
        base[i] = md[i];
    }
    while(e){
        if(e&1){
            calculateSol();
        }
        calculateBase();
        if(sol[0] > P[0]){
            return 1;
        }
        e >>= 1;
    }
    if(sol[0] == P[0]){
        for(i = P[0];i >= 1;i--){
            if(sol[i] > P[i]){
                return 1;
            }else if(sol[i] < P[i]){
                return -1;
            }
        }
        return 0;
    }else if(sol[0] > P[0]){
        return 1;
    }
    return -1;
}

int compareLfAndRg(){
    if(lf[0] == rg[0]){
        for(int i = rg[0];i >= 1;i--){
            if(lf[i] > rg[i]){
                return 1;
            }else if(lf[i] < rg[i]){
                return -1;
            }
        }
        return 0;
    }else if(lf[0] > rg[0]){
        return 1;
    }
    return -1;
}

bool binarySearch(int b){
    initBinarySearch(b);
    calculateMiddle();
    int x;
    while(compareLfAndRg() <= 0){
        x = areEqual(b);
        if(x == 0){
            return 1;
        }else if(x == 1){
            calculateRg();
        }else{
            calculateLf();
        }
        calculateMiddle();
    }
    return 0;
}

int main()
{
    ifstream fin("numere2.in");
    ofstream fout("numere2.out");
    int i;
    fin>>buffer+1;
    P[0] = strlen(buffer+1);
    for(i = 1;i <= P[0];i++){
        P[P[0] - i + 1] = buffer[i] - '0';
    }
    for(i = 100;i >= 1;i--){
        if(binarySearch(i)){
            break;
        }
    }
    int b = i;
    for(i = md[0];i >= 1;i--){
        fout<<md[i];
    }
    fout<<'\n'<<b;
    return 0;
}