Cod sursa(job #2917074)

Utilizator luiz_felipeLuiz Felipe luiz_felipe Data 3 august 2022 00:22:47
Problema Numere 2 Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.9 kb
#include <fstream>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
const char INPUT[] = "numere2.in";
const char OUTPUT[] = "numere2.out";
const int DIM = 305;
char buffer[105];
vector<int> P(DIM), lf(DIM), rg(DIM), middle(DIM), base(DIM), sol(DIM), temp(DIM);

inline int MAX(int a, int b) {
	return a > b ? a : b;
}

inline int CEIL(double x) {
	return (int)x + 1;
}

void InitCautBinar(int b);
void CautMijloc();
void CalculStanga();
void CalculDreapta();
void Baza();
void Solutie();
int SuntEgale(int e);
int ComparaStangaDreapta();
int CautBinar(int b);

int main() {
	ifstream f(INPUT);
	ofstream g(OUTPUT);
	f >> buffer + 1;
	P[0] = strlen(buffer + 1);
	int i;
	for (i = 1; i <= P[0]; ++i) {
		P[P[0] - i + 1] = buffer[i] - 48;
	}
	for (i = 100; i > 0; --i) {
		if (CautBinar(i)) {
			break;
		}
	}
	int b = i;
	for (i = middle[0]; i > 0; --i) {
		g << middle[i];
	}
	g << '\n' << b;
}

void InitCautBinar(int b) {
	rg[0] = CEIL((P[0] + static_cast<double>(1)) / b) + 1;
	lf[0] = MAX(rg[0] - 3, 0);
	lf[lf[0]] = 1;
	fill(rg.begin() + 1, rg.begin() + rg[0], 0);
	rg[rg[0]] = 1;
}

void CautMijloc() {
	int i, t = 0;
	middle[0] = rg[0];
	for (i = 1; i <= middle[0]; ++i) {
		middle[i] = lf[i] + rg[i] + t;
		t = middle[i] / 10;
		middle[i] %= 10;
	}
	middle[++middle[0]] = t ? t : middle[++middle[0]];
	for (i = middle[0]; i > 0; --i) {
		t = t * 10 + middle[i];
		middle[i] = t / 2;
		t %= 2;
	}
	middle[0] = (!(middle[middle[0]] || middle[0] < 2)) ? middle[0] - 1 : middle[0];
}

void CalculStanga() {
	int i, t;
	lf.assign(middle.begin(), middle.begin() + middle[0] + 1);
	for (t = i = 1; i <= lf[0]; ++i) {
		lf[i] += t;
		t = lf[i] / 10;
		lf[i] %= 10;
	}
	lf[++lf[0]] = t ? t : lf[++lf[0]];
}

void CalculDreapta() {
	int i, t;
	rg.assign(middle.begin(), middle.begin() + middle[0] + 1);
	for (t = i = 1; i <= lf[0]; ++i) {
		rg[i] -= t;
		if (rg[i] < 0) {
			rg[i] += 10;
			t = 1;
		}
		else t = 0;
	}
	for (; rg[rg[0]] == 0 && rg[0] > 1; --rg[0]);
}

void Baza() {
	int i, j, t = 0;
	temp[0] = base[0] + base[0] - 1;
	fill(temp.begin() + 1, temp.begin() + temp[0] + 1, 0);
	for (i = 1; i <= base[0]; ++i) {
		for (j = 1; j <= base[0]; ++j) {
			temp[i + j - 1] += base[i] * base[j];
		}
	}
	for (i = 1; i <= temp[0]; ++i) {
		temp[i] += t;
		t = temp[i] / 10;
		temp[i] %= 10;
	}
	temp[++temp[0]] = t ? t : temp[++temp[0]];
	base.assign(temp.begin(), temp.begin() + temp[0] + 1);
}

void Solutie() {
	int i, j, t = 0;
	temp[0] = sol[0] + base[0] - 1;
	fill(temp.begin() + 1, temp.begin() + temp[0] + 1, 0);
	for (i = 1; i <= sol[0]; ++i) {
		for (j = 1; j <= base[0]; ++j) {
			temp[i + j - 1] += sol[i] * base[j];
		}
	}
	for (i = 1; i <= temp[0]; ++i) {
		temp[i] += t;
		t = temp[i] / 10;
		temp[i] %= 10;
	}
	temp[++temp[0]] = t ? t : temp[++temp[0]];
	sol.assign(temp.begin(), temp.begin() + temp[0] + 1);
}

int SuntEgale(int e) {
	sol[0] = sol[1] = 1;
	base.assign(middle.begin(), middle.begin() + middle[0] + 1);
	for (; e; e /= 2) {
		if (e & 1) {
			Solutie();
		}
		Baza();
		if (sol[0] > P[0]) {
			return 1;
		}
	}
	if (sol[0] == P[0]) {
		for (int i = P[0]; i > 0; --i) {
			if (sol[i] > P[i]) {
				return 1;
			}
			else if (sol[i] < P[i]) {
				return -1;
			}
		}
		return 0;
	}
	else return sol[0] > P[0] ? 1 : -1;
}

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

int CautBinar(int b) {
	InitCautBinar(b);
	CautMijloc();
	while (ComparaStangaDreapta() < 1) {
		int x = SuntEgale(b);
		switch (x)
		{
		case 0:
			return 1;
		case 1:
			CalculDreapta();
			break;
		default:
			CalculStanga();
			break;
		}
		CautMijloc();
	}
	return 0;
}