Cod sursa(job #1737965)

Utilizator preda.andreiPreda Andrei preda.andrei Data 5 august 2016 14:18:59
Problema Elimin Scor 0
Compilator c Status done
Runda Arhiva de probleme Marime 3.17 kb
#include <stdio.h>
#include <stdlib.h>

#define NMAX 650

int mat[NMAX][NMAX];
int stiva[NMAX];
int sume[NMAX];

int backtracking(int n, int m, int r, int c);
void sorteazaSume(int st, int dr);
void inter(int *a, int *b);

int main()
{
    FILE *fin = fopen("elimin.in", "r");
    FILE *fout = fopen("elimin.out", "w");

    int n, m, r, c, i, j;
    fscanf(fin, "%d%d%d%d", &n, &m, &r, &c);

    for (i = 1; i <= n; ++i) {
        for (j = 1; j <= m; ++j) {
            fscanf(fin, "%d", &mat[i][j]);
            mat[i][0] += mat[i][j];
            mat[0][j] += mat[i][j];
        }
    }

    int suma = backtracking(n, m, r, c);

    fprintf(fout, "%d", suma);
    return 0;
}

int backtracking(int n, int m, int r, int c)
{
    int mod = (n <= m) ? 1 : 2;
    int limita = (n <= m) ? n : m;
    int finalBack = (n <= m) ? r : c;

    int smax = 0;
    int scur = 0;

    int i, j;
    for (i = 1; i <= n; ++i)
        for (j = 1; j <= m; ++j)
            scur += mat[i][j];

    int nStiva = 1;
    while (nStiva > 0) {
        if (stiva[nStiva] == 0) {
            stiva[nStiva] = stiva[nStiva - 1];
        }
        else {
            scur += (mod == 1) ? mat[stiva[nStiva]][0] : mat[0][stiva[nStiva]];
            if (mod == 1) {
                for (i = 1; i <= m; ++i)
                    mat[0][i] += mat[stiva[nStiva]][i];
            }
            else {
                for (i = 1; i <= n; ++i)
                    mat[i][0] += mat[i][stiva[nStiva]];
            }
        }
        ++stiva[nStiva];

        if (stiva[nStiva] > limita) {
            --nStiva;
        }
        else {
            /// elimin din matrice linia sau coloana curenta
            if (mod == 1) {
                scur -= mat[stiva[nStiva]][0];
                for (i = 1; i <= m; ++i)
                    mat[0][i] -= mat[stiva[nStiva]][i];
            }
            else {
                scur -= mat[0][stiva[nStiva]];
                for (i = 1; i <= n; ++i)
                    mat[i][0] -= mat[i][stiva[nStiva]];
            }

            if (nStiva == finalBack) {
                /// verific solutie
                for (i = 1; i <= n + m - limita; ++i) {
                    sume[i] = (mod == 1) ? mat[0][i] : mat[i][0];
                }

                sorteazaSume(1, limita);

                int sdif = 0;
                for (i = 1; i <= finalBack; ++i)
                    sdif += sume[i];

                if (scur - sdif > smax)
                    smax = scur - sdif;
            }
            else {
                /// urc in stiva
                stiva[++nStiva] = 0;
            }
        }
    }

    return smax;
}

void sorteazaSume(int st, int dr)
{
    if (st >= dr)
        return;

    int i = st + 1, j = dr;
    inter(&sume[st], &sume[st + (dr - st) / 2]);

    while (i <= j) {
        while (i <= j && sume[st] >= sume[i])
            ++i;
        while (i <= j && sume[st] < sume[j])
            --j;
    }
    --i;
    inter(&sume[st], &sume[i]);

    sorteazaSume(st, i - 1);
    sorteazaSume(i + 1, dr);
}

void inter(int *a, int *b)
{
    int aux = *a;
    *a = *b;
    *b = aux;
}