Cod sursa(job #120743)

Utilizator juniorOvidiu Rosca junior Data 6 ianuarie 2008 14:49:33
Problema Diamant Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.63 kb
// Pot fi cel mult 88200? valori distincte

#include <stdio.h>
#include <string.h>

short a[2][21][90001], b[21][90001];
int aux, lna[21], lpa[21], l, c, z, nl, nc, x, v, i0, i1, va, vb, ln, lp;

int main () {
  //sz = 90001*sizeof(int);
  freopen("diamant.in" ,"r",stdin);
  freopen("diamant.out","w",stdout);
  scanf("%d %d %d", &nl, &nc, &x);
  i0 = 0; i1 = 1;
  for (c = 1; c <= nc; c++) {
    a[0][c][45000] = 1;
    lna[c] = lpa[c] = 45000;
  }
  for (l = 1; l <= nl; l++) {
    ln = 45000; lp = 45000; // limita negativa si limita pozitiva
    memset(b, 0, sizeof(b));
    b[0][45000] = 1;
    for (c = 1; c <= nc; c++) {
      for (v = ln; v <= lp; v++) {
        b[c][v-l*c] += b[c-1][v];
        b[c][v    ] += b[c-1][v];
        b[c][v+l*c] += b[c-1][v];
      }
      ln -= l*c; lp += l*c;
      for (vb = ln; vb <= lp; vb++)
        for (va = lna[c]; va <= lpa[c]; va++) {
          z = va+vb-45000; // O anumita valoare pentru z se obtine in mai multe moduri,
          aux = (int)b[c][vb]*(int)a[i0][c][va]%10000; // deci facem o suma.
          a[i1][c][z] += aux;
          if (a[i1][c][z] >= 10000)
            a[i1][c][z] -= 10000;
        }
      lna[c] = 90000-z; lpa[c] = z; // limitele anterioare pentru pasul urmator
    }
    i0 = 1-i0; i1 = 1-i1; // pentru linia urmatoare
    memset(a[i1], 0, sizeof(a)/2);
  }
  printf("%d", a[i0][nc][x+45000]);
  return 0;
}


/*
1,1
       -1  0  1
        1  1  1

1,2
 -3 -2 -1  0  1  2  3
  0  0  0  0  1  1  1
  0  0  1  1  2  1  1
  1  1  2  1  2  1  1

2,1
 -3 -2 -1  0  1  2  3
  1  1  2  1  2  1  1


int a[201];
#define a (a+100)
*/