3692 - maxime: Difference between revisions

From Bitnami MediaWiki
No edit summary
Tag: visualeditor
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.


== 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>
100001
3 1 3 8 1 8
3
2 5 6
<code>maximeOUT.txt</code>
Datele nu corespund restrictiilor impuse


:3 1 3 8 1 8
== Rezolvare ==
 
:3
 
:2 5 6
 
; iesire
 
:Datele introduse corespund restrictiilor impuse.
 
: 2 2 1


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


; intrare
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


:90
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()))


:-4 2 0 8 2 -9
        if not verifica_restricții(n, a, m, queries):
            fout.write("Datele nu corespund restrictiilor impuse")
            return


:-6
        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)


:52 73 58
        for i in range(1, n + 1):
 
            if a[i-1] > maxim:
; iesire
                premaxim, pozpremaxim = maxim, pozmaxim
 
                maxim, pozmaxim = a[i-1], i
:Datele de intrare nu corespund restrictiilor impuse.
                if pozpremaxim >= 1:
 
                    PZ[pozpremaxim] = i
== Rezolvare ==  
                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


<syntaxhighlight lang="python3" line="1"
            st[varf + 1] = i
            varf += 1


def calculeaza_rep(V):
        for i in range(n, 0, -1):
    maxim = 0
            while varf > 0 and a[i-1] > a[st[varf]-1]:
    rep = 0
                varf -= 1
    for val in V:
            DR[i] = 1 + DR[st[varf]] if a[i-1] == a[st[varf]-1] else DR[st[varf]]
        if val > maxim:
             st[varf + 1] = i
             maxim = val
             varf += 1
        elif val == maxim:
             rep += 1
    return rep


def eliminare_element(V, P):
        for p in queries:
    del V[P - 1]
            if CNT[p] == 0:
    return V
                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]]} ")


for P in [2, 5, 8]:
        fout.write("\n") # Scriem un newline la sfârșit pentru a încheia output-ul
    V = eliminare_element(V, P)
    rep = calculeaza_rep(V)
    print(f"După eliminarea elementului de pe poziția {P}, rep = {rep}")


if __name__ == "__main__":
    main()


</syntaxhighlight>
</syntaxhighlight>

Revision as of 22:05, 22 March 2024

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:

(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

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

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.

Restricții și precizări

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

Exemplul 1:

maximeIN.txt

6
3 1 3 8 1 8
3
2 5 6

maximeOUT.txt

2 2 1

Explicație

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:

maximeIN.txt

100001
3 1 3 8 1 8
3
2 5 6

maximeOUT.txt

Datele nu corespund restrictiilor impuse

Rezolvare

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