3692 - maxime: Difference between revisions

From Bitnami MediaWiki
No edit summary
 
(4 intermediate revisions by the same user not shown)
Line 1: Line 1:
== Cerinta ==
== Cerinta ==


Se dă un șir V cu N valori naturale nenule, memorate pe poziții consecutive începând cu poziția 1. Notăm cu S următoarea secvență de cod aplicată asupra sa:
Se dă un șir <code>V</code> cu <code>N</code> valori naturale nenule, memorate pe poziții consecutive începând cu poziția <code>1</code>. Notăm cu <code>S</code> următoarea secvență de cod aplicată asupra sa:


(C/C++)
(C/C++)
maxim = 0;
maxim = 0;
rep = 0;
rep = 0;
for(i = 1; i <= N; i++)
for(i = 1; i <= N; i++)
if(V[i] > maxim)
if(V[i] > maxim)
maxim = V[i];
maxim = V[i];
else
else
if(V[i] == maxim)
if(V[i] == maxim)
rep++;
rep++;
Considerăm operația de eliminare din V a elementului de pe o anumită poziție dată P. În urma operației de eliminare elementele de pe pozițiile P + 1, P + 2, ..., N ajung pe o poziție cu 1 mai mică iar N scade cu 1.
Considerăm operația de eliminare din <code>V</code> a elementului de pe o anumită poziție dată <code>P</code>. În urma operației de eliminare elementele de pe pozițiile <code>P + 1, P + 2, ..., N</code> ajung pe o poziție cu <code>1</code> mai mică iar <code>N</code> scade cu <code>1</code>.


Dându-se mai multe operații de eliminare(independente una de alta, adică fiecare se aplică asupra șirului inițial, nu după operația anterioară), să se determine valoarea variabilei rep dacă am aplica secvența S asupra șirului obținut după fiecare operație de eliminare.
Dându-se mai multe operații de eliminare(independente una de alta, adică fiecare se aplică asupra șirului inițial, nu după operația anterioară), să se determine valoarea variabilei <code>rep</code> dacă am aplica secvența <code>S</code> asupra șirului obținut după fiecare operație de eliminare.


== Date de intrare ==
= Date de intrare =
Fițierul <code>maximeIN.txt</code> conține pe prima linie un număr natural <code>N</code>. Pe linia a doua se află <code>N</code> numere naturale nenule, separate prin câte un spațiu. Pe linia următoare se află un număr <code>M</code> reprezentând numărul de operații de eliminare. Linia următoare conține <code>M</code> numere, cuprinse între <code>1</code> și <code>N</code>, ce reprezină poziția din șir a elementului la care se realizează eliminarea curentă. Numerele de pe această linie sunt separate prin câte un spațiu.


Fisierul maxime.in conține pe prima linie un număr natural N. Pe linia a doua se află N numere naturale nenule, separate prin câte un spațiu. Pe linia următoare se află un număr M reprezentând numărul de operații de eliminare. Linia următoare conține M numere, cuprinse între 1 și N, ce reprezină poziția din șir a elementului la care se realizează eliminarea curentă. Numerele de pe această linie sunt separate prin câte un spațiu.
= Date de ieșire =
Fișierul <code>maximeOUT.txt</code> conține pe primul rând <code>M</code> numere, separate prin câte un spațiu, reprezentând valoarea variabilei <code>rep</code> obținută aplicând secvența <code>S</code> după fiecare operație de eliminare. În cazul în care restricțiile nu sunt îndeplinite, se va afișa mesajul "Datele nu corespund restrictiilor impuse".


== Date de iesire ==
= Restricții și precizări =


Fișierul maxime.out conține pe primul rând M numere, separate prin câte un spațiu, reprezentând valoarea variabilei rep obținută aplicând secvența S după fiecare operație de eliminare.
* <code>2 ≤ N ≤ 100.000</code>
* <code>1 ≤ Vi</code> <code>≤ 100.000</code>
* <code>1 ≤ M ≤ 100.000</code>
* <code>1 ≤ poziție eliminare ≤ N</code>


== Restrictii si precizari ==
= Exemplul 1: =
<code>maximeIN.txt</code>
6
3 1 3 8 1 8
3
2 5 6
<code>maximeOUT.txt</code>
2 2 1


*2 ≤ N ≤ 100.000
=== Explicație ===
*1 ≤ Vi ≤ 100.000
Aplicând prima operație de eliminare, șirul devine: <code>N = 5</code> și <code>V = 3 3 8 1 8</code>, valoarea <code>rep</code> devine <code>2</code>.
*1 ≤ M ≤ 100.000
*1 ≤ poziție eliminare ≤ N


== Exemplul 1 ==
Aplicând a doua operație de eliminare, șirul devine: <code>N = 5</code> și <code>V = 3 1 3 8 8</code>, valoarea <code>rep</code> devine <code>2</code>.


; intrare
Aplicând a treia operație de eliminare, șirul devine: <code>N = 5</code> și <code>V = 3 1 3 8 1</code>, valoarea <code>rep</code> devine <code>1</code>.


:6
== Exemplul 2: ==
 
<code>maximeIN.txt</code>
:3 1 3 8 1 8
100001
 
3 1 3 8 1 8
:3
3
 
2 5 6
:2 5 6
<code>maximeOUT.txt</code>
 
Datele nu corespund restrictiilor impuse
; iesire
 
:Datele introduse corespund restrictiilor impuse.
 
: 2 2 1
 
== Exemplul 2 ==
 
; intrare
 
:9
 
:4 2 4 8 2 9
 
:6
 
:5 7 5
 
; iesire
 
:Datele de intrare nu corespund restrictiilor impuse  


== Rezolvare ==  
== Rezolvare ==  


<syntaxhighlight lang="python3" line="1">
<syntaxhighlight lang="python3" line="1" def="" calculeaza_rep(v):="" maxim="0" rep="0" for="" val="" in="" v:="" if=""> NMAX = 100005
#3692 - maxime
 
#include <iostream>
#include <vector>


using namespace std;
def verifica_restricții(n, a, m, queries):
    """Verifică dacă datele de intrare respectă restricțiile impuse."""
    if not (2 <= n <= 100000):
        return False
    if any(v < 1 or v > 100000 for v in a):
        return False
    if not (1 <= m <= 100000):
        return False
    if any(p < 1 or p > n for p in queries):
        return False
    return True


int main() {
def main():
     int N;
     with open("maximeIN.txt", "r") as fin, open("maximeOUT.txt", "w") as fout:
    cin >> N;
        n = int(fin.readline().strip())
        a = list(map(int, fin.readline().strip().split()))
        m = int(fin.readline().strip())
        queries = list(map(int, fin.readline().strip().split()))


    vector<int> V(N + 1);
        if not verifica_restricții(n, a, m, queries):
    for (int i = 1; i <= N; i++) {
            fout.write("Datele nu corespund restrictiilor impuse")
        cin >> V[i];
            return
    }


    int maxim = 0;
        premaxim = maxim = -1
    int rep = 0;
        pozpremaxim = pozmaxim = -1
        rep = varf = 0
        CNT = [0] * (NMAX + 2)
        PZ = [0] * (NMAX + 2)
        st = [0] * (NMAX + 2)
        DR = [0] * (NMAX + 2)
        OK = [0] * (NMAX + 2)


    // Calculează variabila rep pentru șirul inițial
        for i in range(1, n + 1):
    for (int i = 1; i <= N; i++) {
            if a[i-1] > maxim:
        if (V[i] > maxim) {
                premaxim, pozpremaxim = maxim, pozmaxim
            maxim = V[i];
                maxim, pozmaxim = a[i-1], i
        } else if (V[i] == maxim) {
                if pozpremaxim >= 1:
            rep++;
                    PZ[pozpremaxim] = i
        }
                PZ[pozmaxim] = -1
    }
                CNT[i] = 1
            else:
                while varf > 0 and a[i-1] > a[st[varf]-1]:
                    varf -= 1
                if pozmaxim >= 1 and PZ[pozmaxim] == 0 and a[i-1] >= premaxim:
                    PZ[pozmaxim] = i
                    if a[i-1] == premaxim:
                        OK[pozmaxim] = 1
                if a[i-1] == maxim:
                    CNT[i] = 2
                    rep += 1


    int numar_operatii;
            st[varf + 1] = i
    cin >> numar_operatii;
            varf += 1


    for (int k = 0; k < numar_operatii; k++) {
        for i in range(n, 0, -1):
        int P;
            while varf > 0 and a[i-1] > a[st[varf]-1]:
        cin >> P;
                varf -= 1
            DR[i] = 1 + DR[st[varf]] if a[i-1] == a[st[varf]-1] else DR[st[varf]]
            st[varf + 1] = i
            varf += 1


         // Actualizează variabilele maxim și rep după eliminarea elementului de pe poziția P
         for p in queries:
        if (V[P] == maxim) {
            if CNT[p] == 0:
             rep -= 1;
                fout.write(f"{rep} ")
             V[P] = 0; // Marchează elementul ca eliminat
             elif CNT[p] == 2:
            for (int i = 1; i <= N; i++) {
                fout.write(f"{rep - 1} ")
                 if (V[i] > maxim) {
             elif CNT[p] == 1:
                     maxim = V[i];
                 if OK[p]:
                } else if (V[i] == maxim) {
                     fout.write(f"{1 + rep - DR[p] + DR[PZ[p]]} ")
                    rep++;
                 else:
                 }
                    fout.write(f"{rep - DR[p] + DR[PZ[p]]} ")
            }
        } else {
            // Dacă elementul de pe poziția P nu este maxim, nu modificăm variabilele
            cout << rep << endl;
            continue;
        }


         cout << rep << endl;
         fout.write("\n")  # Scriem un newline la sfârșit pentru a încheia output-ul
    }


     return 0;
if __name__ == "__main__":
}
     main()


</syntaxhighlight>
</syntaxhighlight>

Latest revision as of 22:07, 22 March 2024

Cerinta[edit | edit source]

Se dă un șir V cu N valori naturale nenule, memorate pe poziții consecutive începând cu poziția 1. Notăm cu S următoarea secvență de cod aplicată asupra sa:

(C/C++)

maxim = 0;
rep = 0;
for(i = 1; i <= N; i++)
	if(V[i] > maxim)
		maxim = V[i];
	else
		if(V[i] == maxim)
			rep++;

Considerăm operația de eliminare din V a elementului de pe o anumită poziție dată P. În urma operației de eliminare elementele de pe pozițiile P + 1, P + 2, ..., N ajung pe o poziție cu 1 mai mică iar N scade cu 1.

Dându-se mai multe operații de eliminare(independente una de alta, adică fiecare se aplică asupra șirului inițial, nu după operația anterioară), să se determine valoarea variabilei rep dacă am aplica secvența S asupra șirului obținut după fiecare operație de eliminare.

Date de intrare[edit | edit source]

Fițierul maximeIN.txt conține pe prima linie un număr natural N. Pe linia a doua se află N numere naturale nenule, separate prin câte un spațiu. Pe linia următoare se află un număr M reprezentând numărul de operații de eliminare. Linia următoare conține M numere, cuprinse între 1 și N, ce reprezină poziția din șir a elementului la care se realizează eliminarea curentă. Numerele de pe această linie sunt separate prin câte un spațiu.

Date de ieșire[edit | edit source]

Fișierul maximeOUT.txt conține pe primul rând M numere, separate prin câte un spațiu, reprezentând valoarea variabilei rep obținută aplicând secvența S după fiecare operație de eliminare. În cazul în care restricțiile nu sunt îndeplinite, se va afișa mesajul "Datele nu corespund restrictiilor impuse".

Restricții și precizări[edit | edit source]

  • 2 ≤ N ≤ 100.000
  • 1 ≤ Vi ≤ 100.000
  • 1 ≤ M ≤ 100.000
  • 1 ≤ poziție eliminare ≤ N

Exemplul 1:[edit | edit source]

maximeIN.txt

6
3 1 3 8 1 8
3
2 5 6

maximeOUT.txt

2 2 1

Explicație[edit | edit source]

Aplicând prima operație de eliminare, șirul devine: N = 5 și V = 3 3 8 1 8, valoarea rep devine 2.

Aplicând a doua operație de eliminare, șirul devine: N = 5 și V = 3 1 3 8 8, valoarea rep devine 2.

Aplicând a treia operație de eliminare, șirul devine: N = 5 și V = 3 1 3 8 1, valoarea rep devine 1.

Exemplul 2:[edit | edit source]

maximeIN.txt

100001
3 1 3 8 1 8
3
2 5 6

maximeOUT.txt

Datele nu corespund restrictiilor impuse

Rezolvare[edit | edit source]

<syntaxhighlight lang="python3" line="1" def="" calculeaza_rep(v):="" maxim="0" rep="0" for="" val="" in="" v:="" if=""> NMAX = 100005

def verifica_restricții(n, a, m, queries):

   """Verifică dacă datele de intrare respectă restricțiile impuse."""
   if not (2 <= n <= 100000):
       return False
   if any(v < 1 or v > 100000 for v in a):
       return False
   if not (1 <= m <= 100000):
       return False
   if any(p < 1 or p > n for p in queries):
       return False
   return True

def main():

   with open("maximeIN.txt", "r") as fin, open("maximeOUT.txt", "w") as fout:
       n = int(fin.readline().strip())
       a = list(map(int, fin.readline().strip().split()))
       m = int(fin.readline().strip())
       queries = list(map(int, fin.readline().strip().split()))
       if not verifica_restricții(n, a, m, queries):
           fout.write("Datele nu corespund restrictiilor impuse")
           return
       premaxim = maxim = -1
       pozpremaxim = pozmaxim = -1
       rep = varf = 0
       CNT = [0] * (NMAX + 2)
       PZ = [0] * (NMAX + 2)
       st = [0] * (NMAX + 2)
       DR = [0] * (NMAX + 2)
       OK = [0] * (NMAX + 2)
       for i in range(1, n + 1):
           if a[i-1] > maxim:
               premaxim, pozpremaxim = maxim, pozmaxim
               maxim, pozmaxim = a[i-1], i
               if pozpremaxim >= 1:
                   PZ[pozpremaxim] = i
               PZ[pozmaxim] = -1
               CNT[i] = 1
           else:
               while varf > 0 and a[i-1] > a[st[varf]-1]:
                   varf -= 1
               if pozmaxim >= 1 and PZ[pozmaxim] == 0 and a[i-1] >= premaxim:
                   PZ[pozmaxim] = i
                   if a[i-1] == premaxim:
                       OK[pozmaxim] = 1
               if a[i-1] == maxim:
                   CNT[i] = 2
                   rep += 1
           st[varf + 1] = i
           varf += 1
       for i in range(n, 0, -1):
           while varf > 0 and a[i-1] > a[st[varf]-1]:
               varf -= 1
           DR[i] = 1 + DR[st[varf]] if a[i-1] == a[st[varf]-1] else DR[st[varf]]
           st[varf + 1] = i
           varf += 1
       for p in queries:
           if CNT[p] == 0:
               fout.write(f"{rep} ")
           elif CNT[p] == 2:
               fout.write(f"{rep - 1} ")
           elif CNT[p] == 1:
               if OK[p]:
                   fout.write(f"{1 + rep - DR[p] + DR[PZ[p]]} ")
               else:
                   fout.write(f"{rep - DR[p] + DR[PZ[p]]} ")
       fout.write("\n")  # Scriem un newline la sfârșit pentru a încheia output-ul

if __name__ == "__main__":

   main()

</syntaxhighlight>