Cod sursa(job #2774992)

Utilizator luiz_felipeLuiz Felipe luiz_felipe Data 13 septembrie 2021 20:07:27
Problema Numere 2 Scor 5
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.62 kb
#include <fstream>
#include <algorithm>
#include <cstring>
using namespace std;
ifstream f("numere2.in");
ofstream g("numere2.out");
int P[305], lf[305], rg[305], md[305], base[305], sol[305], tmp[305];
char buffer[105];

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

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

class MyClass{
private:
	void InitCautareBinara(int b);
	void CautareMijloc();
	void CalculareRg();
	void CalculareLf();
	void Solutie();
	void Baza();
	int SuntEgale(int e);
	int CompareLFandRG();
public:
	int CautareBinara(int b);
};

void MyClass::InitCautareBinara(int b)
{
	rg[0] = CEIL((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 MyClass::CautareMijloc()
{
	int i, 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;
	for (i = md[0]; i > 0; --i) {
		T = T * 10 + md[i];
		md[i] = T / 2;
		T %= 2;
	}
	if (!(md[md[0]] || md[0] <= 1)) --md[0];
}

void MyClass::CalculareRg()
{
	int i, T;
	for (i = 0; i <= md[0]; ++i) rg[i] = md[i];
	for (T = i = 1; i <= rg[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 MyClass::CalculareLf()
{
	int i, T;
	for (i = 0; i <= md[0]; ++i) lf[i] = md[i];
	for (T = i = 1; i <= lf[0]; ++i) {
		lf[i] += T;
		T = lf[i] / 10;
		lf[i] %= 10;
	}
	if (T) lf[++lf[0]] = T;
}

void MyClass::Solutie()
{
	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] = 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 MyClass::Baza()
{
	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] = 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 MyClass::SuntEgale(int e)
{
	sol[0] = sol[1] = 1;
	int i;
	for (i = 0; i <= md[0]; ++i) base[i] = md[i];
	for (; e; e /= 2) {
		if (e & 1) Solutie();
		Baza();
		if (sol[0] > P[0]) return 1;
	}
	if (sol[0] == P[0]) {
		for (i = P[0]; i > 0; --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 MyClass::CompareLFandRG()
{
	int i;
	if (lf[0] == rg[0]) {
		for (i = rg[0]; i > 0; --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;
}

int MyClass::CautareBinara(int b)
{
	InitCautareBinara(b);
	CautareMijloc();
	int x;
	while (CompareLFandRG() < 1) {
		x = SuntEgale(b);
		switch (x) {
		case 0:
			return 1;
		case 1:
			CalculareRg();
			break;
		default:
			CalculareLf();
			break;
		}
		CautareMijloc();
	}
	return 0;
}

int main() {
	MyClass mc;
	int i;
	f >> buffer + 1;
	P[0] = strlen(buffer + 1);
	for (i = 1; i <= P[0]; i++)  P[P[0] - i + 1] = buffer[i] - 48;
	for (i = 100; i > 0; --i)
		if (mc.CautareBinara(i)) break;
	int b = i;
	for (i = md[0]; i > 0; --i) g << md[i];
	g << '\n' << b;
}