Cod sursa(job #41361)

Utilizator damaDamaschin Mihai dama Data 28 martie 2007 10:51:32
Problema Numere 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.02 kb
#include <stdio.h>
#include <ctype.h>
#include <string.h>

using namespace std;

bool maimare(int* a, int* b);
bool egal(int* a, int* b);
void add(int* dest, int* a, int* b);
void mul(int* a, int* b);
void div2(int* a);



int nr[128],baza = 4, t[128], min [128], mid[128], max[128], k = 10000,c[128];



int main()
{
	freopen("numere2.in","r",stdin);
	freopen("numere2.out","w",stdout);
	
	char c;
	bool ok = false;
	int i, j, crt;
	
	while (!feof(stdin))
	{
		scanf(" %c ",&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)
	{
		min[0] = 1;
		max[0] = nr[0];
		for(j = 1; j <= nr[0]; ++j)
		{
			max[j] = nr[j];
		}
		while(maimare(max,min) && !ok)
		{
			memset(t,0,sizeof(t));
			add(mid,min,max);
			div2(mid);
			t[0] = 1;
			t[1] = 1;
			for(j = 1; j <= i && maimare(nr,t); ++j)
			{
				mul(t,mid);
			}
			if(egal(nr,t))
			{
				printf("%d",mid[mid[0]]);
				for(j = mid[0] - 1; j > 0; --j)
				{
					printf("%04d",mid[j]);
				}
				printf("\n%d\n",i);
				ok = true;
				break;
			}
			else if(maimare(nr,t))
			{
				crt = 1;
				memcpy(min,mid,sizeof(mid));
				++min[1];
				while(min[crt] == 10000)
				{
					min[crt] = 0;
					++crt;
					++min[crt];
				}
				if(min[0] < crt)
					min[0] = crt;
			}
			else
			{
				crt = 1;
				memcpy(max,mid,sizeof(mid));
				--max[1];
				while(max[crt] == -1)
				{
					max[crt] = 9999;
					++crt;
					--max[crt];
				}
				if(max[max[0]] == 0)
					--max[0];				
			}
		}
	}
	if(!ok)
	{
		printf("%d",nr[nr[0]]);
		for(i = nr[0] - 1; i > 0; --i)
		{
			printf("%04d",nr[i]);
		}
		printf("\n1\n");
	}
	
	
	return 0;
}

bool maimare(int* a, int* b)
{
	int i;
	
	if(a[0] != b[0])
	{
		return (a[0] > b[0]);
	}
	else
	{
		for (i = a[0]; i > 0; --i)
		{
			if(a[i] != b[i])
			{
				return a[i] > b[i];
			}
		}
	}
	return true;
}

bool egal(int* a, int* b)
{
	int i;
	
	if (a[0] != b[0])
	{
		return false;
	}
	else
	{
		for (i = a[0]; i > 0; --i)
		{
			if (a[i] != b[i])
			{
				return false;
			}
		}
	}
	return true;
}

void add(int* dest, int* a, int* b)
{
	int tr,i;
	
	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 div2(int* a)
{
	int i, tmp = a[0];
	
	for(i = a[0]; i > 0; --i)
	{
		if(a[i] % 2 == 1)
		{
			a[i - 1] += k;
		}
		
		a[i] /= 2;
	}
	if(a[tmp] != 0)
	{
		a[0] = tmp;	
	}
	else
	{
		a[0] = tmp - 1;
	}
}

void mul (int* a, int *b)
{
	int i, j, tr;
	memset(c,0,sizeof(c));
	
	for(i = 1; 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;
		}
		if(i + j - 2 > c[0])
		{
			c[0] = i + j - 2;
		}
	}
	memcpy(a,c,sizeof(c));
	
}