Как улучшить работу программы - C (СИ)
Формулировка задачи:
Ув. эксперты помогите улучшить работу программы....
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#define MAX_L 32
#define POW 100000
#define MAX_N 100
#define MAX_K 10
struct long_def
{
int l;
int a[MAX_L];
};
typedef struct long_def long_t;
FILE *fi, *fo;
int dig[MAX_K];
long_t ans_def;
long_t *ans;
int ar_1[MAX_N*MAX_K + 1];
int ar_2[MAX_N*MAX_K + 1];
int *a, *b, *t;
int N, K;
int min (int a, int b) { return (a<b)?a:b; }
int max (int a, int b) { return (a>b)?a:b; }
long_t *
zero (long_t *x)
{
int i;
x->l = 0;
for (i = 0; i < MAX_L; i++)
x->a[i] = 0;
return x;
}
long_t *
one (long_t *x)
{
zero (x);
x->l = 1;
x->a[0] = 1;
return x;
}
long_t *
add_long (long_t *x, long_t *y, long_t *z)
{
int i, r, l;
l = max (x->l, y->l);
r = 0;
for (i = 0; i < l; i++)
{
z->a[i] = x->a[i] + y->a[i] + r;
r = z->a[i] / POW;
z->a[i] %= POW;
}
while (r > 0)
{
z->a[l++] = r % POW;
r /= POW;
}
z->l = l;
return z;
}
long_t *
mul_long (long_t *x, int q, long_t *z)
{
int i, r, l;
l = x->l;
r = 0;
for (i = 0; i < l; i++)
{
z->a[i] = x->a[i] * q + r;
r = z->a[i] / POW;
z->a[i] %= POW;
}
while (r > 0)
{
z->a[l++] = r % POW;
r /= POW;
}
z->l = l;
return z;
}
long_t *
div_long (long_t *x, int q, long_t *z)
{
int i, r, l;
l = x->l;
r = 0;
for (i = l - 1; i >= 0; i--)
{
z->a[i] = r * POW + x->a[i];
r = z->a[i] % q;
z->a[i] /= q;
}
while ((l > 0) && (z->a[l-1] == 0))
l--;
z->l = l;
return z;
}
void
write_long (long_t *x)
{
int i, l;
l = x->l;
fprintf (fo, "%d", x->a[l - 1]);
for (i = l - 2; i >= 0; i--)
{
fprintf (fo, "%05d", x->a[i]);
}
fprintf (fo, "\n");
}
void
count (void)
{
int i, j, d, n;
int s;
long_t tmp_def;
long_t *tmp = &tmp_def;
a = ar_1;
b = ar_2;
s = 0;
for (i = 1; i <= K; i++)
s += dig[i] * i;
if (!(s%2))
{
for (i = 0; i <= s/2; i++)
{
a[i] = 0;
}
a[0] = 1;
for (d = K; d > 0; d--)
{
for (i = 0; i <= s/2; i++)
b[i] = a[i];
for (i = 0; i <= s/2; i++)
{
if (!a[i]) continue;
for (j = 0; j <= dig[d]; j++)
{
b[i + j*d] = 1;
}
}
t = a; a = b; b = t;
}
}
if ((!a[s/2]) || (s%2))
{
n = N;
one (tmp);
for (d = 0; d <= K; d++)
{
for (i = n - dig[d] + 1; i <= n; i++)
mul_long (tmp, i, tmp);
for (i = 2; i <= dig[d]; i++)
div_long (tmp, i, tmp);
n -= dig[d];
}
add_long (ans, tmp, ans);
}
}
void
gen (int d, int s)
{
int i;
if (s > N) return;
if (d > K)
{
dig[0] = N - s;
count ();
return ;
}
for (i = 0; i <= N - s; i++)
{
dig[d] = i;
gen (d + 1, s + i);
}
}
int
main (void)
{
fi = fopen ("input.txt", "rt");
fo = fopen ("output.txt", "wt");
ans = &ans_def;
while (1)
{
if (fscanf (fi, "%d%d", &N, &K) < 2) break;
zero (ans);
gen (1, 0);
write_long (ans);
}
fclose (fi);
fclose (fo);
return 0;
}Решение задачи: «Как улучшить работу программы»
textual
Листинг программы
gen (int d, int s)
{
...
for (i = 0; i <= N - s; i++)
{
dig[d] = i;
gen (d + 1, s + i);
}
}