Rezolvare completă PbInfo #2453 Rosii mici

Dan este un mare pasionat al fructelor, printre preferatele sale fiind strugurii şi pepenii. Însă recent şi-a descoperit și pasiunea pentru legume, în special pentru roşii, dar mai ales roşiile mici. Spre norocul lui, grădina bunicului este plină de roşii. Grădina are forma unei matrice cu N linii și M coloane cu elemente numere naturale, nu neapărat distincte, unde fiecare element din matrice reprezintă dimensiunea unei roşii. Matricea are proprietatea că oricare coloană are valorile ordonate crescător de sus în jos, adică de la prima spre ultima linie. Bunicul său îi cere să rezolve Q sarcini. Pentru fiecare sarcină, Dan primeşte un număr natural x şi trebuie să găsească o submatrice de arie maximă care începe de pe linia 1 a matricei care reprezintă grădina şi are toate elementele mai mici sau egale decât x. Pentru determinarea submatricei cerute, Dan are voie să mute toate valorile unei coloane în fața oricărei alte coloane. De asemenea, îi este permis să facă oricâte mutări de tipul acesta.

Cerința

Să se calculeze aria maximă a unei submatrice care respectă specificațiile din enunț, pentru fiecare din cele Q sarcini date de către bunic.

Date de intrare

Fișierul de intrare rosii_mici.in conține pe prima linie trei numere naturale N, M și Q separate printr-un spaţiu, având semnificația din enunț. Pe fiecare dintre următoarele N linii se află câte M numere naturale despărțite prin câte un spațiu, reprezentând valorile matricei. Pe următoarele Q linii se află câte un număr natural x, reprezentând dimensiunea unei roşii.

Date de ieșire

Fișierul de ieșire rosii_mici.out va conține pe primele Q linii câte un număr natural, reprezentând aria maximă cerută
pentru fiecare sarcină, în ordinea în care acestea apar în fișierul de intrare.

Restricții și precizări

  • 1 ≤ N, M ≤ 1000
  • 1 ≤ Q ≤ 100 000
  • 1 ≤ A[i][j] ≤ N * M, 1 ≤ i ≤ N, 1 ≤ j ≤ M
  • 1 ≤ x ≤ N * M
  • Pentru 30% din punctajul total există teste cu 1 ≤ N, M, Q ≤ 50
  • Pentru alte 20% din punctajul total există teste cu 1 ≤ M ≤ 100

Exemplu

rosii_mici.in

3 4 3
1 9 6 2
1 10 10 4
7 15 10 6
6
10
9

rosii_mici.out

4
9
6

Explicație

Pentru rezolvarea primei sarcini Dan mută prima coloană în fața celei de a patra obținând matricea:
9 6 1 2
10 10 1 4
15 10 7 6
Alege apoi submatricea cu colțul stânga sus în (1,3) și colțul dreapta jos în (2,4). Aria acesteia este 4.

Pentru rezolvarea celei de a doua sarcini, Dan mută prima coloană în fața celei de a treia obținând matricea:
9 1 6 2
10 1 10 4
15 7 10 6
Soluția este submatricea cu colțul stânga sus în (1,2) și colțul dreapta jos în (3,4). Aria acesteia este 9.

Pentru rezolvarea celei de a treia sarcini, Dan mută ultima coloană în fața primei coloane, obținând matricea:
2 1 9 6
4 1 10 10
6 7 15 10
Soluția este submatricea cu colțul stânga sus în (1,1) și colțul dreapta jos în (3,2). Aria acesteia este 6.

Cum e corect?

cout < "As la info"; cout << "As la info"; cout >> "As la info";

Felicitări! Poți mai mult?

Avem sute de probleme pentru tine, fiecare cu explicații ușor de înțeles.

Greșit, dar nu-i bai!

Antrenează-te cu sutele de probleme pe care ți le-am pregătit. Îți explicăm fiecare problemă în parte.

Rezolvare

Iată rezolvarea de 100 de puncte pentru problema Rosii mici:

#include <cstdio>
#include <vector>
#include <fstream>
#include <cassert>
using namespace std;

int main() {
    ifstream fin("rosii_mici.in");
    ofstream fout("rosii_mici.out");
    int n, m, q;
    fin >> n >> m >> q;
    assert(1 <= n && n <= 1000);
    assert(1 <= m && m <= 1000);
    assert(1 <= q && q <= 100000);
    vector<vector<int>> positions(n * m + 5);
    vector<int> minn(m, 0);
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            int x;
            fin >> x;
            assert(minn[j] <= x);
            minn[j] = x;
            assert(1 <= x && x <= n*m);
            positions[x].push_back(j);
        }
    }
    vector<int>height(m + 1, 0), sum(n + 1, 0);
    vector<int>ans(n * m + 5, 0);
    int sol = 0;
    for (int val = 1;val <= n*m; ++val) {
        for(auto j: positions[val]) {
            height[j]++;
            sum[height[j]]++;
            sol = max(sol,sum[height[j]] * height[j]);
        }
        ans[val] = sol;
    }
    for (int i = 1; i <= n*m; i++) 
        ans[i] = max(ans[i-1], ans[i]);
    while(q-- > 0) {
        int x;
        fin >> x;
        assert(1 <= x && x <= n*m);
        fout << ans[x] << "\n";
    }
    return 0;
} 

Atenție

Enunțurile afișate pe această pagină aparțin exclusiv site-ului PbInfo. Astfel, pentru ștergerea conținutului, puteți să ne contactați la adresa Adresa de email.

Rezolvarea problemei #2453 Rosii mici

Pe această pagină găsești rezolvarea de 100 de puncte pentru problema #2453 Rosii mici de pe PbInfo.ro. Atenție: nu încurajăm copiatul codului! Totuși, credem cu tărie că analizarea unei soluții corecte este o metodă foarte ușoară de a învăța informatică, astfel că oferim sursele pentru peste 1500 de probleme de pe platforma PbInfo.ro.

Pentru rezolvări PbInfo de la peste 1500 de probleme, vă invităm să intrați pe site-ul nostru!