Cod sursa(job #3191641)

Utilizator ioanabaduIoana Badu ioanabadu Data 10 ianuarie 2024 11:52:02
Problema Diamant Scor 20
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.16 kb
#include <iostream>
#include <fstream>
#define MODULO 10000
#define X_MAX 200000

using namespace std;
ifstream in("diamant.in");
ofstream out("diamant.out");

int n, m, x;    
int dp[2][X_MAX];

int main (){
   int valMax;

   in >> n >> m >> x;

   valMax = n*(n+1)*m*(m+1); //practic sunt doua sume gauss inmultite
   valMax >>= 2; // se imparte la patru 

   if (x > valMax || x < -valMax){
      cout << 0; // clar nu se poate obtine un astfel de dimanat
      return 0;
   }

   dp[1][valMax] = dp[1][valMax-1] = dp[1][valMax+1] = 1;
   int idx1 = 0, idx2 = 1; // eu ma teoretic o matrice pentru a rezolva problema asta cu programare dinamica, care deoarece am nevoie doar de 
   // linia anterioare, atunci ma folosesc doar de doua siruri (de acea am declarat matricea dp doar cu doua linii)
   // scriu una in functie de celalalta

   for (int i=2; i<=n*m; ++i){ // numarul de obiecte pe care il am (mai putin primul pe care il initializez pentru dp)
      int lin, col, nr;

      lin = i/m; // echivalentul la a parcurge matricea [n][m] si a lua toate elementele si a le pune intr-un sir, dar se castiga la O
      col = i%m;
      if(col == 0)
         col = m;
      else
         lin++;

      nr = lin * col;

      idx1 = 1 - idx1;
      idx2 = 1 - idx2;// practic interschimb cele doua linii (pentru a avea sens dp)

      // mai jos parcurg toate valorile pe care le poate lua x (pt fiecare numar de obiecte luate (i))
      // am valMax*2, deoarece primele valMax valori (worth of the dimant) reprezinte cele negative, iar alte valMax cele pozitive
      // incep de la 0, pentru a avea o valoare (worth of the dimant) in plus, care reprezinta valoarea 0
      for (int j=0; j<=valMax*2; ++j){
         dp[idx2][j] = dp[idx1][j];

         if (j + nr <= valMax*2){ // conditile astea is ca sa nu am !signal 11!
            dp[idx2][j] += dp[idx1][j+nr];
         }
         if (j - nr >= 0){
            dp[idx2][j] += dp[idx1][j-nr];
         }

         if (dp[idx2][j] >= MODULO)
            dp[idx2][j] -= MODULO; // e mai usor de facut operatia "-" decat "%"
      }
   }
   
   out << dp[idx2][valMax+x];
   return 0;
}