Cod sursa(job #1723524)

Utilizator AndreiRSStatescu Andrei Rares AndreiRS Data 30 iunie 2016 20:50:56
Problema Elimin Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 5.36 kb
#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;

struct pereche {
    int index;
    int suma;
};

int cmp_pereche_by_sum(pereche p1, pereche p2) {
    return p1.suma < p2.suma;
}

int** malloc_matrix(int NumRows, int NumCols)
{
    int** mat = new int*[NumRows];
    for (int i = 0; i < NumRows; i++)
    {
        mat[i] = new int[NumCols];
        for (int j = 0; j < NumCols; j++)
        {
            mat[i][j] = 0;
        }
    }
    return mat;
}


void brute()
{
    ifstream fi("elimin.in");
    ofstream fo("elimin.out");

    int M, N;
    int R, C;
    int S = 0;

    fi >> M >> N >> R >> C;
    int mat[M+1][N+1];

    for (int i = 0; i < M; i++)
    {
        for (int j = 0; j < N; j++)
        {
            fi >> mat[i][j];
        }
    }

    for (int nr = 0; nr < (1<<M); nr++)
    {
        int cnt = 0;
        for (int bit = 0; bit < M; bit++)
        {
            if ((nr >> bit) & 1)
            {
                cnt++;
            }
        }

        if (cnt != R) continue;

        for (int nr2 = 0; nr2 < (1<<N); nr2++)
        {
            cnt = 0;
            for (int bit = 0; bit < N; bit++)
            {
                if ((nr2 >> bit) & 1)
                {
                    cnt++;
                }
            }

            if (cnt != C) continue;

            int sum = 0;

            for (int bit = 0; bit < M; bit++)
            {
                if ((nr >> bit) & 1) continue;

                for (int bit2 = 0; bit2 < N; bit2++)
                {
                    if ((nr2 >> bit2) & 1) continue;

                    sum += mat[bit][bit2];
                }
            }

            if (S < sum) {
                S = sum;

                if (S == 117) {

                    for (int bit = 0; bit < M; bit++)
                        printf("%d", (nr >> bit)&1);
                    printf("\n");
                    for (int bit = 0; bit < N; bit++)
                        printf("%d", (nr2 >> bit)&1);
                    printf("\n");
                    printf("\n");
                }
            }
        }
    }

    fo << S;

    fi.close();
    fo.close();
}

void greedy()
{
    ifstream fi("elimin.in");
    ofstream fo("elimin.out");

    int M, N;
    int R, C;
    int S = 0;

    fi >> M >> N >> R >> C;

    int mat[M+1][N+1];
    pereche linii[M+1];
    pereche coloane[N+1];

    for (int i = 0; i < M; i++)
    {
        linii[i].index = i;
        linii[i].suma = 0;
    }

    for (int j = 0; j < N; j++)
    {
        coloane[j].index = j;
        coloane[j].suma = 0;
    }

    for (int i = 0; i < M; i++)
    {
        for (int j = 0; j < N; j++)
        {
            fi >> mat[i][j];

            linii[i].suma += mat[i][j];
        }
    }

    sort(linii, linii+M, cmp_pereche_by_sum);

    for (int i2 = R; i2 < M; i2++)
    {
        int i = linii[i2].index;

        for (int j = 0; j < N; j++)
        {
            coloane[j].suma += mat[i][j];
        }
    }

    sort(coloane, coloane+N, cmp_pereche_by_sum);

    for (int i2 = R; i2 < M; i2++)
    {
        int i = linii[i2].index;

        for (int j2 = C; j2 < N; j2++)
        {
            int j = coloane[j2].index;

            S += mat[i][j];
        }
    }



    for (int i = R; i < M; i++)
        printf("%d ", linii[i].index);
    printf("\n");
    for (int j = C; j < N; j++)
        printf("%d ", coloane[j].index);
    printf("\n");

    fo << S;

    fi.close();
    fo.close();
}

void back(int pos, int NumRows, int NumCols, int NumRowsEliminated, int NumColsEliminated, int* sol, int** mat, int* sum_col, int &S)
{
    if (pos == NumRowsEliminated + 1)
    {
        pereche cols[NumCols];
        for (int col = 0; col < NumCols; col++)
        {
            cols[col].index = col;
            cols[col].suma = sum_col[col];
        }

        sort(cols, cols + NumCols, cmp_pereche_by_sum);

        int s = 0;

        for (int col = NumRowsEliminated; col < NumCols; col++)
        {
            s += cols[col].suma;
        }

        if (s > S)
        {
            S = s;
        }

        return;
    }

    for (int row = sol[pos-1] + 1; row < NumRows; row++)
    {
        sol[pos] = row;

        for (int col = 0; col < NumCols; col++)
        {
            sum_col[col] -= mat[row][col];
        }

        back(pos + 1, NumRows, NumCols, NumRowsEliminated, NumColsEliminated, sol, mat, sum_col, S);

        for (int col = 0; col < NumCols; col++)
        {
            sum_col[col] += mat[row][col];
        }
    }
}

void gensub()
{
    ifstream fi("elimin.in");
    ofstream fo("elimin.out");

    int M, N;
    int R, C;
    int S = 0;

    fi >> M >> N >> R >> C;

    int** mat = malloc_matrix(M, N);

    int* sum_col = new int[M];
    for (int j = 0; j < N; j++)
    {
        sum_col[j] = 0;
    }

    int sol[M-R+1];

    for (int i = 0; i < M; i++)
    {
        for (int j = 0; j < N; j++)
        {
            fi >> mat[i][j];
            sum_col[j] += mat[i][j];
        }
    }

    sol[0] = -1;
    back(1, M, N, R, C, sol, mat, sum_col, S);

    fo << S;

    fi.close();
    fo.close();
}

int main()
{
    //brute();
    //greedy();
    gensub();

    return 0;
}