fbpx

Problema #2435 – fadema – Rezolvari PBInfo

de Mihai-Alexandru

Corina a cumpărat de la magazin un material din pânză colorată, de formă dreptunghiulară pentru a decupa din el o față de masă pentru masa din bucătărie. Fiindcă este pasionată de șah, Corina a ales un material format din n x m pătrate de aceeași dimensiune colorate cu alb sau negru. Pătratele sunt lipite și sunt dispuse pe linii și coloane paralele cu laturile dreptunghiului din pânză care a fost cumpărat. Două pătrate se numesc vecine dacă au în comun o latură. Materialul din pânză nu respectă neapărat structura unei table de șah, adică pătratele vecine pe aceeași linie sau pe aceeași coloană nu sunt în mod necesar colorate în mod alternativ.

Corina a cumpărat de la magazin un material din pânză colorată, de formă dreptunghiulară pentru a decupa din el o față de masă pentru masa din bucătărie. Fiindcă este pasionată de șah, Corina a ales un material format din n x m pătrate de aceeași dimensiune colorate cu alb sau negru. Pătratele sunt lipite și sunt dispuse pe linii și coloane paralele cu laturile dreptunghiului din pânză care a fost cumpărat. Două pătrate se numesc vecine dacă au în comun o latură. Materialul din pânză nu respectă neapărat structura unei table de șah, adică pătratele vecine pe aceeași linie sau pe aceeași coloană nu sunt în mod necesar colorate în mod alternativ.
Corina își propune prin urmare să decupeze un dreptunghi cu un număr maxim de pătrate, paralel cu laturile dreptunghiului din pânză care a fost cumpărat, care să respecte alternanța culorilor pe o tablă de șah.

Cerința

Să se determine numărul maxim de pătrate întregi ale unui dreptunghi cu laturile paralele cu cele ale materialului cumpărat, care poate fi decupat astfel încât să nu existe două pătrate vecine având aceeași culoare.

Date de intrare

Fișierul de intrare fadema.in conține pe prima linie două numere naturale n și m reprezentând numărul de linii, respectiv numărul de coloane ale materialului din pânză care a fost cumpărat. Pe fiecare dintre următoarele n linii se află câte m cifre 0 sau 1 despărțite prin câte un spațiu, reprezentând culorile pătratelor materialului. Cifra 0 codifică culoarea albă, iar cifra 1 codifică culoarea neagră.

Date de ieșire

Fișierul de ieșire fadema.out va conține pe prima linie un singur număr natural A, reprezentând numărul maxim de pătrate ale unui dreptunghi care poate fi decupat astfel încât să respecte cerința din enunț. Dacă nu există dreptunghiuri cu cel puțin două pătrate având culori alternante, se va scrie valoarea 1.

Restricții și precizări

  • 2 ≤ N ≤ 1000
  • 2 ≤ M ≤ 1000
  • Pentru rezolvarea corectă a cerinței respectând restricțiile problemei se acordă 90 de puncte,
  • Pentru rezultate corecte respectând restricțiile problemei și n, m ≤ 100 se acordă 20 de puncte
  • Pentru rezultate corecte respectând restricțiile problemei și n, m ≤ 200 se acordă 40 de puncte
  • Pentru rezultate corecte respectând restricțiile problemei și n, m ≤ 400 se acordă 65 de puncte
  • În concurs s-au acordat 10 puncte din oficiu. Aici se acordă 10 puncte pentru exemplele din enunț.

Exemplul 1:

fadema.in

3 4 
0 0 1 0 
1 1 0 0 
1 0 1 0

fadema.out

6

Explicație

Dreptunghiul delimitat de liniile 1 și 3, respectiv coloanele 2 și 3 are 6 pătrate.

Exemplul 2:

fadema.in

4 5 
0 1 1 0 1
1 0 1 0 1
0 0 1 1 0
1 1 0 1 1

fadema.out

5

Explicație

Dreptunghiul delimitat de linia 2, respectiv coloanele 1 și 5 are 5 pătrate.

#include <bits/stdc++.h>


using namespace std;

ifstream cin("fadema.in");
ofstream cout("fadema.out");

const int MaxN = 1001;

int h[MaxN][MaxN];
const int Nmax=1001;

bool a[Nmax][Nmax];
int mat[Nmax][Nmax] , mat1[Nmax][Nmax] , n , m;

int maxAreaInHist(int x[], int L)
{
    stack<int> st;

    int j = 0, tp;
    int amax = 0, area;

    while (j < max(n , m))
    {
        if (st.empty() || x[st.top()] <=  x[j])
            st.push(j++);
        else
        {
            tp = st.top();
            st.pop();
            area = x[tp] * (st.empty() ? j : j - st.top() - 1);
            amax = max(amax, area);
        }
    }

    while (!st.empty())
    {
        tp = st.top();
        st.pop();
        area = x[tp] * (st.empty() ? j : j - st.top() - 1);
        amax = max(amax, area);
    }

    return amax;
}

int main()
{
    cin >> n >> m;
    for(int i = 0 ; i < n ; ++i)
        for(int j = 0 ; j < m ; ++j)
            cin >> a[i][j];
    mat[0][0]=1;
    for(int i = 1 ; i < m ; ++i)
        mat[0][i]=!mat[0][i-1];
    for(int i = 1 ; i < n ; ++i)
        for(int j = 0 ; j < m ; ++j)
            if(j==0)
                mat[i][j]=!mat[i-1][j];
            else
                mat[i][j]=!mat[i][j-1];
    for(int i = 0 ; i < n ; ++i)
        for(int j = 0 ; j < m ; ++j)
            if(mat[i][j]!=a[i][j])
                mat1[i][j]=0;
            else
                mat1[i][j]=1;
    for(int i = 0 ; i < n ; ++i)
        for(int j = 0 ; j < m ; ++j)
            a[i][j]=mat1[i][j];
    int maxArea = 0;
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            if (a[i][j] == 0)
                h[i][j] = 0;
            else
            {
                if ( i == 0 )
                    h[i][j] = 1;
                else
                    h[i][j] = h[i - 1][j] + 1;
            }

    int area;
    for (int i = 0; i < max(n , m); i++)
    {
        area = maxAreaInHist(h[i], i);
        if (area > maxArea)
            maxArea = area;
    }
    for(int i = 0 ; i < n ; ++i)
        for(int j = 0 ; j < m ; ++j)
            a[i][j]=!a[i][j];
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            if (a[i][j] == 0)
                h[i][j] = 0;
            else
            {
                if ( i == 0 )
                    h[i][j] = 1;
                else
                    h[i][j] = h[i - 1][j] + 1;
            }
    for (int i = 0; i < max(n , m); i++)
    {
        area = maxAreaInHist(h[i], i);
        if (area > maxArea)
            maxArea = area;
    }
    cout << maxArea;
}
Comentarii

S-ar putea sa iti placa