3692 - maxime: Difference between revisions

From Bitnami MediaWiki
Pagină nouă: == 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 aj...
 
No edit summary
Tag: visualeditor
 
(8 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="pyton3" line="1">
<syntaxhighlight lang="python3" line="1" def="" calculeaza_rep(v):="" maxim="0" rep="0" for="" val="" in="" v:="" if=""> NMAX = 100005
 
#include <iostream>
#include <vector>
 
using namespace std;
 
int main() {
    int N;
    cin >> N;
 
    vector<int> V(N + 1);
    for (int i = 1; i <= N; i++) {
        cin >> V[i];
    }
 
    int maxim = 0;
    int rep = 0;
 
    // Calculează variabila rep pentru șirul inițial
    for (int i = 1; i <= N; i++) {
        if (V[i] > maxim) {
            maxim = V[i];
        } else if (V[i] == maxim) {
            rep++;
        }
    }
 
    int numar_operatii;
    cin >> numar_operatii;
 
    for (int k = 0; k < numar_operatii; k++) {
        int P;
        cin >> P;
 
        // Actualizează variabilele maxim și rep după eliminarea elementului de pe poziția P
        if (V[P] == maxim) {
            rep -= 1;
            V[P] = 0; // Marchează elementul ca eliminat
            for (int i = 1; i <= N; i++) {
                if (V[i] > maxim) {
                    maxim = V[i];
                } else if (V[i] == maxim) {
                    rep++;
                }
            }
        } else {
            // Dacă elementul de pe poziția P nu este maxim, nu modificăm variabilele
            cout << rep << endl;
            continue;
        }
 
        cout << rep << endl;
    }


     return 0;
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


</synttaxhighlight>
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()


; iesire
</syntaxhighlight>

Latest revision as of 22:07, 22 March 2024

Cerinta[edit]

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]

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]

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]

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

Exemplul 1:[edit]

maximeIN.txt

6
3 1 3 8 1 8
3
2 5 6

maximeOUT.txt

2 2 1

Explicație[edit]

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]

maximeIN.txt

100001
3 1 3 8 1 8
3
2 5 6

maximeOUT.txt

Datele nu corespund restrictiilor impuse

Rezolvare[edit]

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