Cod sursa(job #878003)

Utilizator Andrei1998Andrei Constantinescu Andrei1998 Data 13 februarie 2013 18:24:18
Problema Numarare triunghiuri Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.86 kb
#include <cstdio>

using namespace std;

//Matricea initiala
int m[502][502];

//Matricea dinamica, in care se vor tine rezultatele pentru un anumit rest al impartirii la 3
int din[502][502][3];

//Functia determina maximul dintre doua numere
int maxim(int a,int b)
{
    if(a>b)
        return a;
    return b;
}

//Functia determina maximul dintre trei numere
int maxim(int a,int b,int c)
{
    return maxim(maxim(a,b),c);
}

int main()
{
    //Deschiderea fisierelor de intrare si iesire
    freopen("maxtri.in","r",stdin);
    freopen("maxtri.out","w",stdout);

    //Se declara si citeste marimea matricei
    int n;
    scanf("%d",&n);

    //Doua contoare
    int i,j;

    //Se citeste matricea initiala
    for(i=1;i<=n;i++)
        for(j=1;j<=n;j++)
            scanf("%d",&m[i][j]);


    //Prima linie si prima coloana din matricea dinamica pot fi initializate fara calcule prealabile folosind observatia
    //ca exista un singur drum de la (1,1) pana la un element de pe prima linie sau de pe prima coloana
    //Initial suma elementelor de pe prima linie este 0
    int sum=0;

    //Se initializeaza prima linie
    for(i=1;i<=n;i++)
    {
        sum+=m[1][i];
        din[1][i][sum%3]=sum;
    }

    //Initial suma elementelor de pe prima coloana este 0
    sum=0;

    //Se initializeaza prima coloana
    for(i=1;i<=n;i++)
    {
        sum+=m[i][1];
        din[i][1][sum%3]=sum;
    }

    //Se aplica relatia de recurenta pe restul matricei
    for(i=2;i<=n;i++)
        for(j=2;j<=n;j++)
        {
            if(m[i][j]%3==0)
            {
                //Atunci cand toti cei trei "predecesori" ai elementului curent din matricei
                //sunt 0 inseamna ca nu exista un drum cu suma elementelor
                //modulo 3 congruenta cu 0, deci nu trebuie sa modificam acest element al matricei
                if(din[i][j-1][0]>0 || din[i-1][j][0]>0 || din[i-1][j-1][0]>0)
                    din[i][j][0]=maxim(din[i][j-1][0],din[i-1][j][0],din[i-1][j-1][0])+m[i][j];

                //Analog
                if(din[i][j-1][1]>0 || din[i-1][j][1]>0 || din[i-1][j-1][1]>0)
                    din[i][j][1]=maxim(din[i][j-1][1],din[i-1][j][1],din[i-1][j-1][1])+m[i][j];

                //Analog
                if(din[i][j-1][2]>0 || din[i-1][j][2]>0 || din[i-1][j-1][2]>0)
                    din[i][j][2]=maxim(din[i][j-1][2],din[i-1][j][2],din[i-1][j-1][2])+m[i][j];
            }
            else if(m[i][j]%3==1) //Analog, numai ca acum nu mai facem update pe aceleasi resturi, ci pe succesorul lor modulo 3
            {
                if(din[i][j-1][0]>0 || din[i-1][j][0]>0 || din[i-1][j-1][0]>0)
                    din[i][j][1]=maxim(din[i][j-1][0],din[i-1][j][0],din[i-1][j-1][0])+m[i][j];

                if(din[i][j-1][1]>0 || din[i-1][j][1]>0 || din[i-1][j-1][1]>0)
                    din[i][j][2]=maxim(din[i][j-1][1],din[i-1][j][1],din[i-1][j-1][1])+m[i][j];

                if(din[i][j-1][2]>0 || din[i-1][j][2]>0 || din[i-1][j-1][2]>0)
                    din[i][j][0]=maxim(din[i][j-1][2],din[i-1][j][2],din[i-1][j-1][2])+m[i][j];
            }
            else if(m[i][j]%3==2) //Analog, update pe resturi +2 (modulo 3)
            {
                if(din[i][j-1][0]>0 || din[i-1][j][0]>0 || din[i-1][j-1][0])
                    din[i][j][2]=maxim(din[i][j-1][0],din[i-1][j][0],din[i-1][j-1][0])+m[i][j];

                if(din[i][j-1][1]>0 || din[i-1][j][1]>0 || din[i-1][j-1][1])
                    din[i][j][0]=maxim(din[i][j-1][1],din[i-1][j][1],din[i-1][j-1][1])+m[i][j];

                if(din[i][j-1][2]>0 || din[i-1][j][2]>0 || din[i-1][j-1][2]>0)
                    din[i][j][1]=maxim(din[i][j-1][2],din[i-1][j][2],din[i-1][j-1][2])+m[i][j];
            }
        }


    //Se afiseaza raspunsul problemei
    printf("%d\n",din[n][n][0]);

    return 0;
}