Cod sursa(job #2751767)

Utilizator NeacsuMihaiNeacsu Mihai NeacsuMihai Data 15 mai 2021 19:31:34
Problema Ferma2 Scor 40
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.88 kb
#include <iostream>
#include <fstream>

#define NMAX 1000
#define KMAX 1000

using namespace std;

ifstream fin ("ferma2.in");
ofstream fout ("ferma2.out");

int v[NMAX + 1][NMAX + 1];
int rsp[3][KMAX + 1];

int max3(int a, int b, int c){
    if(a >= b && a >= c){
        return a;
    }
    if(b >= a && b >= c){
        return b;
    }
    return c;
}

int main()
{
    int N, K;
    fin >> N >> K;

    for(int i = 1; i <= N; i++){
        for(int j = 1; j <= i; j++){
            fin >> v[i][j];
        }
    }

    for(int ct = 1; ct <= K; ct++){
        for(int i = ct; i <= N; i++){
            rsp[0][ct] += v[i][ i - ct + 1 ];
        }
    }

    for(int i = 1; i <= K; i++){
        rsp[0][i] += rsp[0][i - 1]; //ca sa fac suma partiala
    }

    for(int ct = 1; ct <= K; ct++){
        for(int i = ct; i <= N; i++){
            rsp[1][ct] += v[i][ct];
        }
    }

    for(int i = 1; i <= K; i++){
        rsp[1][i] += rsp[1][i - 1]; //ca mai sus, suma partiala
    }

    for(int ct = 1; ct <= K; ct++){
        for(int j = 1; j <= N - ct + 1; j++){
            rsp[2][ct] += v[N - ct + 1][ j ];
        }
    }
    for(int i = 1; i <= K; i++){
        rsp[2][i] += rsp[2][i - 1]; //ca mai sus, suma partiala
    }


    int ct = K;
    int k0 = 0, k1 = 0, k2 = 0;

    int profitTotal = 0;

    while(ct >= 1){
        int potential0 = rsp[0][k0 + ct] - rsp[0][k0];
        int potential1 = rsp[1][k1 + ct] - rsp[0][k1];
        int potential2 = rsp[2][k2 + ct] - rsp[0][k2];

        int maxim = max3(potential0, potential1, potential2);

        if(maxim == potential0){

            k0++;
            ///cout << "Am ales 0\nadaug la profit " << rsp[0][k0] - rsp[0][k0 - 1] << "\n";
            profitTotal = profitTotal + rsp[0][k0] - rsp[0][k0 - 1]; //adica rsp[0][k0] fara suma partiala

            //actualizez rsp[1][]
            for(int i = k0; i <= N && i - k0 + 1 <= K; i++){
                int x = i;
                int y = i - k0 + 1;

                for(int j = y; j <= K; j++){
                    rsp[1][j] = rsp[1][j] - v[x][y];
                }
            }

            //actualizez rsp[2][]
            for(int i = N; i >= k0 && N - i + 1 >= 1; i--){
                int x = i;
                int y = i - k0 + 1;

                for(int j = N - x + 1; j <= K; j++){
                    //il scad pe v[x][y] din fiecare rsp[2][j]
                    rsp[2][j] = rsp[2][j] - v[x][y];
                }
            }
        }

        else if(maxim == potential1){
            k1++;
            ///cout << "Am ales 1\nadaug la profit " << rsp[1][k1] - rsp[1][k1 - 1] << "\n";
            profitTotal = profitTotal + rsp[1][k1] - rsp[1][k1 - 1]; //adica rsp[1][k1] fara suma partiala

            //actualizez rsp[0][]
            for(int i = k1; i <= N; i++){
                int x = i;
                int y = k1;

                int aux = N - x + y;
                aux = N - aux + 1;


                for(int j = aux; j <= K; j++){
                    rsp[0][j] = rsp[0][j] - v[x][y];
                }
            }

            //actualizez rsp[2][]
            for(int i = N; i >= k1 && N - i + 1 <= K; i--){
                int x = i;
                int y = k1;

                for(int j = N - i + 1; j <= K; j++){
                    rsp[2][j] = rsp[2][j] - v[x][y];
                }
            }

        }

        else if(maxim == potential2){
            k2++;
            ///cout << "Am ales 2\nadaug la profit " << rsp[2][k2] - rsp[2][k2 - 1] << "\n";
            profitTotal = profitTotal + rsp[2][k2] - rsp[2][k2 - 1]; //adica rsp[2][k2] fara suma partiala

            //actualizez rsp[1][]
            //acum iterez pe orizontala
            for(int y = 1; y <= N - k2 + 1 && y <= K; y++){ // am evitat sa pun j pentru ca l-am mai folosit inainte dar cu alta semnificatie si nu vreau sa se faca confuzie
                int x = N - k2 + 1;
                //y = y

                for(int j = y; j <= K; j++){
                    rsp[1][j] = rsp[1][j] - v[x][y];
                }
            }

            //actualizez rsp[0][]
            for(int y = N - k2 + 1; y >= 1 && N + 2 - k2 - y <= K; y--){
                int x = N - k2 + 1;

                int aux = N - x + y;
                aux = N - aux + 1;
                //cout << "( " << x << ", " << y << " ) : " << aux << "\n";

                for(int j = aux; j <= K; j++){
                    rsp[0][j] = rsp[0][j] - v[x][y];
                }
            }
            //cout << "\n";
        }

        /*
        for(int i = 0; i <= 2; i++){
            for(int j = 1; j <= K; j++){
                cout << rsp[i][j] << ' ';
            }
            cout << "\n";
        }
        cout << "\n";
        */

        ct--;
    }

    fout << profitTotal;

    return 0;
}