1839 - Memory006: Diferență între versiuni

De la Universitas MediaWiki
Fără descriere a modificării
Fără descriere a modificării
Linia 6: Linia 6:


== Date de intrare ==
== Date de intrare ==
Fișierul de intrare memory006.in conține
Fișierul de intrare memory006.in conține pe prima linie numerele n şi k, iar pe a doua linie n numere naturale nenule, separate prin spații.
 
== Date de ieșire ==
Fișierul de ieșire memory006.out va conține:
Dacă datele sunt introduse corect, pe ecran se va afișa:  
Dacă datele sunt introduse corect, pe ecran se va afișa:  
'''"Datele sunt introduse corect."''', apoi pe un rând nou '''numărul S, reprezentând numărul secvenţelor din şir care au produsul elementelor egal cu 2k.''', reprezentând valoarea cerută. În cazul contrar, se va afișa pe ecran: '''"Datele nu corespund restricțiilor impuse."'''.
'''"Datele sunt introduse corect."''', apoi pe un rând nou '''numărul S, reprezentând numărul secvenţelor din şir care au produsul elementelor egal cu 2k.''', reprezentând valoarea cerută. În cazul contrar, se va afișa pe ecran: '''"Datele nu corespund restricțiilor impuse."'''.
== Date de ieșire ==
Fișierul de ieșire memory006.out va conține pe prima linie numărul S, reprezentând numărul secvenţelor din şir care au produsul elementelor egal cu 2k.


== Restricţii şi precizări ==
== Restricţii şi precizări ==
Linia 24: Linia 23:
: 7 4 2 4 5
: 7 4 2 4 5
; Ieșire
; Ieșire
: Datele sunt introduse correct
: memory006.out
: memory006.out
: Datele sunt introduse correct
: 2
: 2


Linia 31: Linia 30:
; Intrare
; Intrare
: memory006.in
: memory006.in
: 5 3 2 3
: 5 15000
: 7 4 2 4 5
: 7 4 2 4 5
; Ieșire
; Ieșire
: Datele nu corespund restricțiilor impuse.
: memory006.out
: memory006.out
: Datele nu corespund restricțiilor impuse.
: Datele nu corespund restricțiilor impuse
: 1


== Rezolvare ==  
== Rezolvare ==  
Linia 43: Linia 42:
# 1839 - Memory006
# 1839 - Memory006


def citire_date():
def count_subarrays(n, k, arr):
     n = int(input())
     count = 0
     v = list(map(int, input().split()))
    prod = 1
     return n, v
     left = 0
   
    for right in range(n):
        prod *= arr[right]
       
        while prod > (2 ** 64) / 2 ** k:
            prod //= arr[left]
            left += 1
       
        if prod == 2 ** k:
            count += right - left + 1
   
     return count


def secvmax(n, v):
if __name__ == '__main__':
    st = dr = st_max = dr_max = suma_max = suma = 0
     with open('memory006.in', 'r') as f_in:
     for i in range(n):
         n, k = map(int, f_in.readline().split())
         if v[i] % 2 == 0:
         arr = list(map(int, f_in.readline().split()))
            suma += v[i]
            dr = i
            if suma > suma_max or (suma == suma_max and dr - st > dr_max - st_max):
                suma_max = suma
                st_max = st
                dr_max = dr
         else:
            suma = 0
            st = i + 1
    return st_max + 1, dr_max + 1


def validare(n, v):
    if max(arr) > 10 ** 18 or min(arr) < 1 or k > 10000 or n > 500000:
    if len(v) != n:
         print("Datele nu corespund restricțiilor impuse.")
         return False
     else:
     for x in v:
         print("Datele sunt introduse corect.")
         if x < 1 or x > 10**18:
        print(count_subarrays(n, k, arr))
            return False
    return True


if __name__ == '__main__':
    n, v = citire_date()
    if validare(n, v):
        st, dr = secvmax(n, v)
        print("Datele sunt introduse corect.")
        print(st, dr)
    else:
        print("Datele nu corespund restricțiilor impuse.")




Linia 84: Linia 75:
</syntaxhighlight>
</syntaxhighlight>
== Explicatie Rezolvare ==
== Explicatie Rezolvare ==
Funcția citeste_date_intrare citește numerele n și k de pe prima linie a fișierului de intrare, apoi citește sirul de n numere de pe a doua linie și le returnează sub formă de tuplu (n, k, sir).
Funcția count_subarrays primește ca argumente lungimea șirului n, numărul natural k și șirul de numere naturale nenule arr. Returnează numărul de subșiruri ale șirului arr care au produsul elementelor egal cu 2^k.
Funcția numara_secvente primește numerele n, k și sirul sir și returnează numărul de secvențe ale sir care au produsul egal cu 2 ** k.
 
Pentru a număra secvențele cu produsul egal cu 2 ** k, vom parcurge sirul de la stânga la dreapta și vom menține un produs curent inițial egal cu 1 și un număr de secvențe inițial egal cu 0. La fiecare pas, vom înmulți produsul curent
În cadrul funcției, inițializăm count la 0, prod la 1 și left la 0. Parcurgem șirul arr cu un indice right și actualizăm prod înmulțind cu fiecare element arr[right]. În timp ce prod depășește o anumită valoare calculată cu ajutorul lui k, actualizăm prod împărțind cu elementele de la începutul subșirului până când prod este mai mic sau egal cu acea valoare.
 
Dacă prod este egal cu 2^k, incrementăm count cu numărul de elemente din subșirul curent.
 
În funcția main, citim datele de intrare din fișierul memory006.in și verificăm dacă acestea corespund restricțiilor impuse în enunțul problemei. Dacă datele sunt valide, apelăm funcția count_subarrays și afișăm rezultatul. Dacă datele nu sunt valide, afișăm un mesaj corespunzător.

Versiunea de la data 13 mai 2023 22:22

Sursa: - Memory006


Cerinţa

Se dă un şir format din n numere naturale nenule. Să se afle numărul secvenţelor din şir care au produsul elementelor egal cu 2k, unde k este un număr natural dat.


Date de intrare

Fișierul de intrare memory006.in conține pe prima linie numerele n şi k, iar pe a doua linie n numere naturale nenule, separate prin spații.

Date de ieșire

Fișierul de ieșire memory006.out va conține: Dacă datele sunt introduse corect, pe ecran se va afișa: "Datele sunt introduse corect.", apoi pe un rând nou numărul S, reprezentând numărul secvenţelor din şir care au produsul elementelor egal cu 2k., reprezentând valoarea cerută. În cazul contrar, se va afișa pe ecran: "Datele nu corespund restricțiilor impuse.".

Restricţii şi precizări

  • 1 ≤ n ≤ 500.000
  • 1 ≤ k ≤ 10.000
  • numerele de pe a doua linie a fișierului de intrare vor fi mai mari decât 1 şi mai mici decât 10^18

Exemplu 1

Intrare
memory006.in
5 3
7 4 2 4 5
Ieșire
Datele sunt introduse correct
memory006.out
2

Exemplu 2

Intrare
memory006.in
5 15000
7 4 2 4 5
Ieșire
Datele nu corespund restricțiilor impuse.
memory006.out
Datele nu corespund restricțiilor impuse

Rezolvare

Rezolvare ver. 1

# 1839 - Memory006

def count_subarrays(n, k, arr):
    count = 0
    prod = 1
    left = 0
    
    for right in range(n):
        prod *= arr[right]
        
        while prod > (2 ** 64) / 2 ** k:
            prod //= arr[left]
            left += 1
        
        if prod == 2 ** k:
            count += right - left + 1
    
    return count

if __name__ == '__main__':
    with open('memory006.in', 'r') as f_in:
        n, k = map(int, f_in.readline().split())
        arr = list(map(int, f_in.readline().split()))

    if max(arr) > 10 ** 18 or min(arr) < 1 or k > 10000 or n > 500000:
        print("Datele nu corespund restricțiilor impuse.")
    else:
        print("Datele sunt introduse corect.")
        print(count_subarrays(n, k, arr))

Explicatie Rezolvare

Funcția count_subarrays primește ca argumente lungimea șirului n, numărul natural k și șirul de numere naturale nenule arr. Returnează numărul de subșiruri ale șirului arr care au produsul elementelor egal cu 2^k.

În cadrul funcției, inițializăm count la 0, prod la 1 și left la 0. Parcurgem șirul arr cu un indice right și actualizăm prod înmulțind cu fiecare element arr[right]. În timp ce prod depășește o anumită valoare calculată cu ajutorul lui k, actualizăm prod împărțind cu elementele de la începutul subșirului până când prod este mai mic sau egal cu acea valoare.

Dacă prod este egal cu 2^k, incrementăm count cu numărul de elemente din subșirul curent.

În funcția main, citim datele de intrare din fișierul memory006.in și verificăm dacă acestea corespund restricțiilor impuse în enunțul problemei. Dacă datele sunt valide, apelăm funcția count_subarrays și afișăm rezultatul. Dacă datele nu sunt valide, afișăm un mesaj corespunzător.