Cod sursa(job #582605)

Utilizator ProtomanAndrei Purice Protoman Data 15 aprilie 2011 16:40:45
Problema Pavare2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.38 kb
#include <algorithm>
#include <stdio.h>
#include <locale>

#define MAX 256
#define bazaNum 10

using namespace std;

int n, a, b;
int nrmPosAlb[MAX][MAX], nrmPosNegru[MAX][MAX];
char buffIn[MAX];
int nrmSol[MAX], nrmPoz[MAX];

inline void aduna(int *nrmSum, int nrmTer[])
{
	int i, t = 0;
	for (i = 1; i <= max(nrmSum[0], nrmTer[0]) || t; i++, t /= bazaNum)
		nrmSum[i] = (t += nrmSum[i] + nrmTer[i]) % bazaNum;

	nrmSum[0] = i - 1;
}

inline void scade(int *nrmDif, int nrmScz[])
{
    int i, nrTemp = 0;

    for (i = 1; i <= nrmDif[0]; i++)
         nrmDif[i] += (nrTemp = (nrmDif[i] -= nrmScz[i] + nrTemp) < 0) * bazaNum;
    for (; nrmDif[0] > 1 && !nrmDif[nrmDif[0]]; nrmDif[0]--);
}

inline int compara(int *nrmN1, int *nrmN2)
{
	if (nrmN1[0] > nrmN2[0])
		return 1;
	else if (nrmN1[0] < nrmN2[0])
		return -1;

	for (int i = nrmN1[0]; i; i--)
		if (nrmN1[i] > nrmN2[i])
			return 1;
		else if (nrmN1[i] < nrmN2[i])
			return -1;
	
	return 0;
}

inline void incearca(int ult)
{
	if (ult == 1)
	{
		for (int pun = min(n, a); pun; pun--)
			if (compara(nrmPoz, nrmPosNegru[n - pun]) == 1)
				scade(nrmPoz, nrmPosNegru[n - pun]);
			else
			{
				for (int i = 1; i <= pun; i++)
					printf("%d", 0);
				n -= pun;
				incearca(0);

				break;
			}
	}
	else
	{
		for (int pun = 1; pun <= min(n, b); pun++)
			if (compara(nrmPoz, nrmPosAlb[n - pun]) == 1)
				scade(nrmPoz, nrmPosAlb[n - pun]);
			else
			{
				for (int i = 1; i <= pun; i++)
					printf("%d", 1);
				n -= pun;
				incearca(1);

				break;
			}
	}
}

int main()
{
	freopen("pavare2.in", "r", stdin);
	freopen("pavare2.out", "w", stdout);

	scanf("%d %d %d\n", &n, &a, &b);

	for (fgets(buffIn, MAX, stdin); isalnum(buffIn[nrmPoz[0]]); nrmPoz[0]++)
		nrmPoz[nrmPoz[0] + 1] = buffIn[nrmPoz[0]] - '0';
	reverse(nrmPoz + 1, nrmPoz + 1 + nrmPoz[0]);

	nrmPosAlb[0][0] = nrmPosAlb[0][1] = 1;
	nrmPosNegru[0][0] = nrmPosNegru[0][1] = 1;
	for (int i = 0; i < n; i++)
	{
		for (int j = i + 1; j <= i + a; j++)
			aduna(nrmPosAlb[j], nrmPosNegru[i]);
		for (int j = i + 1; j <= i + b; j++)
			aduna(nrmPosNegru[j], nrmPosAlb[i]);
	}

	aduna(nrmSol, nrmPosAlb[n]);
	aduna(nrmSol, nrmPosNegru[n]);

	for (int i = nrmSol[0]; i; i--)
		printf("%d", nrmSol[i]);
	printf("\n");

	incearca(1);
	if (n)
		incearca(0);

	fclose(stdin);
	fclose(stdout);
	return 0;
}