Rezolvare completă PbInfo #1080 Livada

Norocosul Gigel tocmai a primit în dar de la bunicul său, Nelu, o imensă plantaţie de pomi fructiferi. Fost profesor de geometrie, Nelu a plantat în mod riguros pomii fructiferi pe m rânduri paralele, iar pe fiecare rând a plantat exact câte n pomi fructiferi. Însă, din motive mai mult sau mai puţin obiective, domnul Nelu nu a plantat pe fiecare rând toţi pomii de acelaşi soi, ci din mai multe soiuri diferite. Soiurile de pomi plantaţi în livadă sunt codificate cu numere naturale cuprinse între 1 şi p.

Cuprins de febra rigurozităţii matematice şi de cea a statisticii, Gigel a definit noţiunea de soi majoritar astfel: dacă pe un rând k format din n pomi fructiferi avem cel puţin [n/2]+1 pomi de acelaşi soi x, atunci spunem că soiul x este soi majoritar pe rândul k (prin [y] se înţelege partea întreagă a numărului real y).

Cerinţă

Cunoscând numerele m, n şi p, precum şi soiul fiecărui pom de pe fiecare rând al plantaţiei, ajutaţi-l pe Gigel să determine:

  1. pe câte rânduri din livadă există un soi majoritar;
  2. care este cel mai mare număr de pomi de acelaşi soi plantaţi în poziţii consecutive pe un rând.

Date de intrare

Fișierul de intrare livada.in conține pe prima linie trei numere naturale m, n şi p cu semnificaţia din enunţ, iar pe fiecare dintre următoarele m linii se găsesc câte n numere, despărţite prin câte un spaţiu, reprezentând soiurile pomilor de pe rândul respectiv.

Date de ieșire

Fișierul de ieșire livada.out va conține două linii:

  1. pe prima linie se va scrie un număr natural reprezentând numărul de rânduri din livadă pe care există un soi majoritar;
  2. pe a doua linie se va scrie un număr natural reprezentând cel mai mare număr de pomi de același soi plantaţi în poziţii consecutive pe un rând.

Restricții și precizări

  • 1 ≤ m ≤ 100
  • 1 ≤ n ≤ 700.000
  • 1 ≤ m*n ≤ 700.000
  • 1 ≤ p ≤ 998.560.000
  • Pe fiecare rând diferenţa dintre valoarea maximă şi cea minimă este cel mult 250.000.
  • Dacă doar valoarea de pe prima linie este corectă, se acordă 40% din punctaj. Dacă doar valoarea de pe a doua linie este corectă, se acordă 60% din punctaj. Dacă ambele valori sunt corecte, se acordă 100% din punctajul testului respectiv.

Exemplu

livada.in

4 7 9
2 1 2 3 8 2 2
4 7 2 4 9 7 4
5 5 2 5 5 5 7
2 3 2 3 2 3 1

livada.out

2
3

Explicație

Plantaţia este formată din m=4 rânduri, iar pe fiecare rând avem câte n=7 pomi.

Pentru ca un soi sa fie majoritar pe un rând trebuie ca pe acel rând să existe cel puţin [7/2]+1 = 4 pomi din soiul respectiv.

Există soiuri majoritare pe două rânduri: primul şi al treilea.

Pe rândul al treilea exista 3 poziții consecutive în care se află pomi din același soi (soiul 5).

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 Livada:

//varianta optima - O(m*n)

#include<stdio.h>

int   v[700000]; 

int main()
{
    int m,n,p;
    
    FILE *fin=fopen("livada.in","r");
    FILE *fout=fopen("livada.out","w");
    
    fscanf(fin,"%d %d %d",&m,&n,&p);
    
    int max=0;
    int rsm=0;
    
    for(int i=0;i<m;i++)
    {
        for(int j=0;j<n;j++)
            fscanf(fin,"%d",&v[j]);
    
        int rmax=0;
        int j=0;
        while(j<n-1)
        {
            int k=j+1;
            while((k<n)&&(v[k]==v[j]))
                k++;
            if(k-j>rmax)
                rmax=k-j;
            j=k;
        }
        
        if(rmax>max) max=rmax;
        
        int sm=v[0];
        int cnt=1;
        
        for(int j=1;j<n;j++)
            if(cnt==0)
            {
                sm=v[j];
                cnt=1;
            }
            else
                if (v[j]==sm) cnt++;
                    else cnt--;

        if(cnt==0) sm=0;
        else
        {
            cnt=0;
            for(int j=0;j<n;j++)
                if(v[j]==sm) cnt++;
            if(cnt<n/2+1) sm=0;
        }
            
        if(sm!=0) rsm++;
    }
    
    fprintf(fout,"%d
%d",rsm,max);
    
    fclose(fin);
    fclose(fout);
    
    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 #1080 Livada

Pe această pagină găsești rezolvarea de 100 de puncte pentru problema #1080 Livada 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!