Cod sursa(job #71331)

Utilizator scapryConstantin Berzan scapry Data 10 iulie 2007 10:50:40
Problema Pascal Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.89 kb
#include <assert.h>
#include <stdio.h>

enum { divs = 3 };
const int div[divs] = { 2, 3, 5 };

int base;
int want[divs];
int ans;

void decomp(int val, int d[divs])
{
	assert(val > 0);

	//printf("val %d: ", val);

	for(int i = 0; i < divs; i++)
	{
		d[i] = 0;
		while(val % div[i] == 0)
		{
			val /= div[i];
			d[i]++;
		}
	}

	//printf("left %d, d[] %d %d %d\n", val, d[0], d[1], d[2]);
}

#define FAST

#ifdef FAST
#define validate(x) ;
#else
void validate(const int a[divs])
{
	for(int i = 0; i < divs; i++)
		assert(a[i] >= 0);
}
#endif

void multiply(int a[divs], const int b[divs])
{
	validate(a);
	validate(b);

	for(int i = 0; i < divs; i++)
		a[i] += b[i];

	validate(a);
}

void divide(int a[divs], const int b[divs])
{
	validate(a);
	validate(b);

	for(int i = 0; i < divs; i++)
		a[i] -= b[i];

	validate(a);
}

bool divides(const int a[divs], const int b[divs])
{
	validate(a);
	validate(b);

	for(int i = 0; i < divs; i++)
		if(a[i] < b[i])
			return false;

	return true;
}

void go()
{
	int i, cur[divs], tmp[divs];
	decomp(1, cur); //C(0, base)

	for(i = 1; i < (base + 1) / 2; i++) //C(i, base) and C(base - i, base)
	{
		decomp(base - i + 1, tmp);
		multiply(cur, tmp);
		decomp(i, tmp);
		divide(cur, tmp);

		if(divides(cur, want))
			ans++;

		//printf("i %d. cur %d %d %d\n", i, cur[0], cur[1], cur[2]);
	}

	printf("half ans %d\n", ans);
	ans *= 2;

	if((base + 1) % 2) //one more, in the middle, C(base/2, base)
	{
		i = base / 2;

		decomp(base - i + 1, tmp);
		multiply(cur, tmp);
		decomp(i, tmp);
		divide(cur, tmp);

		if(divides(cur, want))
			ans++;

		//printf("i %d. cur %d %d %d\n", i, cur[0], cur[1], cur[2]);
	}

	printf("final ans %d\n", ans);
}

int main()
{
	int tmp;
	FILE *f = fopen("pascal.in", "r");
	if(!f) return 1;

	fscanf(f, "%d%d", &base, &tmp);
	decomp(tmp, want);

	fclose(f);
	f = fopen("pascal.out", "w");
	if(!f) return 1;

	go();

	fprintf(f, "%d\n", ans);
	fclose(f);
	return 0;
}