Cod sursa(job #448369)

Utilizator ScrazyRobert Szasz Scrazy Data 3 mai 2010 16:55:42
Problema Pavare2 Scor 55
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.3 kb
#include <cstdio>
#include <cstdlib>
#include <cstring>

/*
struct bigNum
{
	int a[10000];
};
*/
#define BASE 1000000000

const int maxn = 100;

int dp[maxn][maxn][2][100];
int sum[100];
int kk[100];

char s[1000];

int n, a, b, k;

void add(int A[], int B[])
{
      int i, t = 0;
      for (i=1; i<=A[0] || i<=B[0] || t; i++, t/=BASE)
              A[i] = (t += A[i] + B[i]) % BASE;
      A[0] = i - 1;
}

void sub(int A[], int B[])
{
      int i, t = 0;
      for (i = 1; i <= A[0]; i++)
              A[i] += (t = (A[i] -= ((i <= B[0]) ? B[i] : 0) + t) < 0) * 10;
      for (; A[0] > 1 && !A[A[0]]; A[0]--);
}

int greater(int A[], int B[])
{
	if (A[0] > B[0]) return 1;
	if (A[0] < B[0]) return 0;

	for (int i = 1; i <= A[0]; i++)
	{
		if (A[i] > B[i]) return 1;
		if (A[i] < B[i]) return 0;
	}
	return 1;
}

int greater2(int A[], int B[])
{
	if (A[0] > B[0]) return 1;
	if (A[0] < B[0]) return 0;

	for (int i = 1; i <= A[0]; i++)
	{
		if (A[i] > B[i]) return 1;
		if (A[i] < B[i]) return 0;
	}
	return 0;
}
/*
void print_sum(int n)
{
	long long sum = 0;
	for (int i = 1; i <= a; ++i)
		sum += dp[n][i][0];
	for (int i = 1; i <= b; ++i)
		sum += dp[n][i][1];
	printf("%lld\n", sum);
}
*/

void output(int a[])
{
    int i;

    printf("%d", a[a[0]]);
    for (i = a[0]-1; i > 0; i--)
        printf("%09d", a[i]);
    printf("\n");
}


void big_sum(int n)
{
	memset(sum, 0, sizeof(sum));
	for (int i = 1; i <= a; ++i)
		add(sum, dp[n][i][0]);
	for (int i = 1; i <= b; ++i)
		add(sum, dp[n][i][1]);
	output(sum);
}

void calc(int n, int opt, int size)
{
	memset(sum, 0, sizeof(sum));
	for (int i = 1; i <= size; ++i)
		add(sum, dp[n][i][opt]);
	//output(sum);
}


void convert(int A[], int b)
{
	A[0] = 0;
	while (b)
	{
		A[++A[0]] = b%BASE;
		b /= BASE;
	}
}

int main()
{
	
	freopen("pavare2.in","r",stdin);
	freopen("pavare2.out","w",stdout);
	
	scanf("%d%d%d%d", &n, &a, &b, &k);

	dp[0][0][0][0] = 1; dp[0][0][0][1] = 1; 
	dp[0][0][1][0] = 1; dp[0][0][1][1] = 1;
	//length
	for (int i = 1; i <= n; ++i)
	{
		//white
		for (int j = 1; j <= a && j <= i; ++j)
		{
			//dp[i][j][0] = dp[i - 1][j - 1][0];
			dp[i][j][0][0] = 0;
			if (i - j >= 0)
			for (int k = 0; k <= b && k <= i - j; ++k)
				add(dp[i][j][0], dp[i - j][k][1]);
		}

		//black
		for (int j = 1; j <= b && j <= i; ++j)
		{
			//dp[i][j][1] = dp[i - 1][j - 1][1];
			dp[i][j][1][0] = 0;
			if (i - j >= 0)
			for (int k = 0; k <= a && k <= i - j; ++k)
				add(dp[i][j][1], dp[i - j][k][0]);
		}
		//print_sum(i);
		//big_sum(i);
	}

	//print_sum(n);
	big_sum(n);

	convert(kk, k);

	int zero[100];
	zero[0] = 1;
	zero[1] = 0;

	int db = 0;
	while(greater2(kk,zero) && n > 0)
	{
		calc(n, 0, a);
		if (greater(sum,kk))//lehet 0-val kezdeni  sum >= 0
		{
			int akt = a;
			while (greater2(kk, dp[n][akt][0])) // sum > 0
			{
				sub(kk, dp[n][akt][0]);
				akt--;
			}

			for (int i = db; i < db + akt; i++)
				s[i] = '0';

			db += akt;
			if (n - akt > 0)
			{
				s[db++] = '1';
				akt++;
			}
			//sub(kk, dp[n][akt][0]);
			n -= akt;

		}
		else
		{
			s[db++] = '1';
			calc(n, 0, a);
			sub(kk, sum);
			n--;
		}
	}

	for (int i = 0; i < db; ++i)
		printf("%c", s[i]);
	printf("\n");

	return 0;
}