0300 - SumaInSecv: Difference between revisions

From Bitnami MediaWiki
Flaviu (talk | contribs)
No edit summary
Flaviu (talk | contribs)
No edit summary
 
(3 intermediate revisions by 2 users not shown)
Line 10: Line 10:


== Date de ieșire ==  
== Date de ieșire ==  
Fişierul de ieşire sumainsecv.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 '''secv10.out va conține pe prima linie numerele lmax și c, reprezentând lungimea maximă a unei secvențe de elemente divizibile cu 10, respectiv numărul de secvențe de lungime maximă cu elemente divizibile cu 10''', reprezentând valoarea cerută. În cazul contrar, se va afișa pe ecran: '''"Datele nu corespund restricțiilor impuse."'''.
'''"Datele sunt introduse corect."''și fișierul secv10.out va conține pe prima linie numerele lmax și c, reprezentând lungimea maximă a unei secvențe de elemente divizibile cu 10, respectiv numărul de secvențe de lungime maximă cu elemente divizibile cu 10''', reprezentând valoarea cerută. În cazul contrar, se va afișa pe ecran: '''"Datele nu corespund restricțiilor impuse."'''.
 


== Restricţii şi precizări ==
== Restricţii şi precizări ==
Line 26: Line 25:
: 12 10 15 7 17 13 19 14
: 12 10 15 7 17 13 19 14
; Ieșire
; Ieșire
: Datele sunt introduse correct
: secv10.out
: secv10.out
: Datele sunt introduse correct
: 2 4  
: 2 4  
== Exemplu 2 ==
== Exemplu 2 ==
; Intrare
; Intrare
: secv10.in
: secv10.in
: 8 32
: 0 32  
: 12 10 15 7 17 13 19 14
:  
; Ieșire
; Ieșire
: secv10.out
: Datele nu corespund restricțiilor impuse.
: Datele nu corespund restricțiilor impuse.
: 5 1
 
== Rezolvare ==  
== Rezolvare ==  
=== Rezolvare ver. 1 ===
=== Rezolvare ver. 1 ===
Line 43: Line 41:
# 0300 - SumaInSecv
# 0300 - SumaInSecv


def citire_date():
def secv_suma(n, S, v):
     n, s = map(int, input().split())
     dp = [[0 for j in range(n)] for i in range(n)]
    v = []
 
     for i in range(n):
     for i in range(n):
         v.extend(map(int, input().split()))
         dp[i][i] = v[i]
     return n, s, v
        for j in range(i+1, n):
            dp[i][j] = dp[i][j-1] + v[j]
 
     lmax = c = 0


def suma_in_secventa(n, s, v):
    suma = 0
    st = 0
    dr = 0
     for i in range(n):
     for i in range(n):
         suma += v[i]
         for j in range(i, n):
        dr += 1
            if dp[i][j] == S:
        while suma > s:
                l = j-i+1
            suma -= v[st]
                if l > lmax:
            st += 1
                    lmax = l
        if suma == s:
                    c = 1
            return st + 1, dr
                elif l == lmax:
     return 0, 0
                    c += 1
 
    if lmax == 0:
        return 0, 0
     else:
        return lmax, c


def validare(n, s, v):
def validate_input(n, S, v):
    if not (1 <= n <= 100):
        return False
     if len(v) != n:
     if len(v) != n:
         return False
         return False
     for x in v:
     for i in range(n):
         if x < 1 or x > 9999:
         if not (1 <= v[i] <= 9999):
             return False
             return False
     return True
     return True


if __name__ == '__main__':
if __name__ == "__main__":
     n, s, v = citire_date()
     try:
    if validare(n, s, v):
        with open("sumainsecv.in") as f:
            n, S = map(int, f.readline().split())
            v = []
            for i in range(n):
                row = f.readline().split()
                if len(row) != 1:
                    raise ValueError("Datele nu corespund restricțiilor impuse.")
                v.append(int(row[0]))
            if not validate_input(n, S, v):
                raise ValueError("Datele nu corespund restricțiilor impuse.")
         print("Datele sunt introduse corect.")
         print("Datele sunt introduse corect.")
         st, dr = suma_in_secventa(n, s, v)
         lmax, c = secv_suma(n, S, v)
         if st == 0 and dr == 0:
         with open("secv10.out", "w") as f:
            print("0 0")
             f.write(f"{lmax} {c}")
        else:
     except Exception as e:
             print(st, dr)
     else:
         print("Datele nu corespund restricțiilor impuse.")
         print("Datele nu corespund restricțiilor impuse.")
        print(e)




Line 88: Line 100:
== Explicatie Rezolvare ==
== Explicatie Rezolvare ==


`secv_suma(n, S, v)`: Această funcție primește trei argumente: `n` - lungimea listei `v`, `S` - suma căutată și `v` - lista de numere întregi. Scopul funcției este să găsească cea mai lungă subsecvență continuă a listei `v` a cărei sumă este egală cu `S`. Funcția utilizează o abordare dinamică pentru a calcula matricea `dp` care stochează sumele parțiale ale subsecvențelor. Apoi, se verifică fiecare subsecvență pentru a determina cea mai lungă subsecvență cu suma `S`. Funcția returnează un tuplu `(lmax, c)` unde `lmax` este lungimea celei mai lungi subsecvențe și `c` este numărul de subsecvențe cu aceeași lungime maximă.
`validate_input(n, S, v)`: Această funcție primește trei argumente: `n` - lungimea listei `v`, `S` - suma căutată și `v` - lista de numere întregi. Scopul funcției este să valideze datele de intrare conform restricțiilor impuse. Verifică dacă lungimea listei `v` este `n`, dacă `n` se încadrează în intervalul permis și dacă fiecare element din `v` se încadrează în intervalul permis. Returnează `True` dacă datele sunt valide și `False` în caz contrar.


citire_date() primeste de la input n si s, urmate de n numerele ale vectorului v. Folosind extend, toate numerele vectorului sunt citite intr-o singura lista.
Funcția principală `if __name__ == "__main__"` citeste datele de intrare din fișierul "sumainsecv.in", validează datele folosind funcția `validate_input()`, apoi apelează funcția `secv_suma()` pentru a obține rezultatul dorit. Rezultatul este scris în fișierul "secv10.out". Dacă apar erori în citirea sau validarea datelor, se afișează un mesaj corespunzător pe ecran.
suma_in_secventa() cauta o secventa a vectorului v cu suma elementelor egala cu s, folosind un algoritm de tip sliding window, care tine minte in st si dr indecsii de start si sfarsit ai secventei. Daca gaseste o astfel de secventa, returneaza indecsii acesteia. Daca nu exista o astfel de secventa, returneaza 0 0.
validare() verifica daca datele de intrare sunt corecte, adica vectorul sa aiba n elemente si toate elementele sa fie intre 1 si 9999.
In functia principala, mai intai se verifica daca datele de intrare sunt corecte folosind validare(). Daca da, se afiseaza un mesaj de confirmare si se apeleaza suma_in_secventa() pentru a determina indecsii secventei cu suma egala cu s. Daca nu exista o astfel de secventa, se afiseaza "0 0". Daca exista, se afiseaza indecsii acesteia. Daca datele de intrare nu sunt corecte, se afiseaza un mesaj corespunzator.

Latest revision as of 21:37, 14 May 2023

Sursa: 0300 - SumaInSecv


Cerinţa[edit | edit source]

Se dă un vector format din n elemente, numere naturale nenule, şi un număr natural S. Determinaţi, dacă există o secvenţă de elemente din şir cu suma elementelor egală cu S.


Date de intrare[edit | edit source]

Fişierul de intrare sumainsecv.in conţine pe prima linie numerele n şi S; urmează cele n elemente ale vectorului, dispuse pe mai multe linii şi separate prin spaţii.


Date de ieșire[edit | edit source]

Dacă datele sunt introduse corect, pe ecran se va afișa: "Datele sunt introduse corect."și fișierul secv10.out va conține pe prima linie numerele lmax și c, reprezentând lungimea maximă a unei secvențe de elemente divizibile cu 10, respectiv numărul de secvențe de lungime maximă cu elemente divizibile cu 10, reprezentând valoarea cerută. În cazul contrar, se va afișa pe ecran: "Datele nu corespund restricțiilor impuse.".

Restricţii şi precizări[edit | edit source]

  • 1 ≤ n ≤ 100
  • elementele vectorului vor avea cel mult 4 cifre şi sunt numerotate de la 1 la n
  • dacă vectorul nu conţine nici o secvenţă cu suma elementelor S, se va afişa 0 0
  • dacă şirul conţine mai multe secvenţe cu suma elementelor egală cu S, se va determina cea mai din stânga

Exemplu 1[edit | edit source]

Intrare
secv10.in
8 32
12 10 15 7 17 13 19 14
Ieșire
Datele sunt introduse correct
secv10.out
2 4

Exemplu 2[edit | edit source]

Intrare
secv10.in
0 32
Ieșire
Datele nu corespund restricțiilor impuse.

Rezolvare[edit | edit source]

Rezolvare ver. 1[edit | edit source]

<syntaxhighlight lang="python" line>

  1. 0300 - SumaInSecv

def secv_suma(n, S, v):

   dp = [[0 for j in range(n)] for i in range(n)]
   for i in range(n):
       dp[i][i] = v[i]
       for j in range(i+1, n):
           dp[i][j] = dp[i][j-1] + v[j]
   lmax = c = 0
   for i in range(n):
       for j in range(i, n):
           if dp[i][j] == S:
               l = j-i+1
               if l > lmax:
                   lmax = l
                   c = 1
               elif l == lmax:
                   c += 1
   if lmax == 0:
       return 0, 0
   else:
       return lmax, c

def validate_input(n, S, v):

   if not (1 <= n <= 100):
       return False
   if len(v) != n:
       return False
   for i in range(n):
       if not (1 <= v[i] <= 9999):
           return False
   return True

if __name__ == "__main__":

   try:
       with open("sumainsecv.in") as f:
           n, S = map(int, f.readline().split())
           v = []
           for i in range(n):
               row = f.readline().split()
               if len(row) != 1:
                   raise ValueError("Datele nu corespund restricțiilor impuse.")
               v.append(int(row[0]))
           if not validate_input(n, S, v):
               raise ValueError("Datele nu corespund restricțiilor impuse.")
       print("Datele sunt introduse corect.")
       lmax, c = secv_suma(n, S, v)
       with open("secv10.out", "w") as f:
           f.write(f"{lmax} {c}")
   except Exception as e:
       print("Datele nu corespund restricțiilor impuse.")
       print(e)


</syntaxhighlight>

Explicatie Rezolvare[edit | edit source]

`secv_suma(n, S, v)`: Această funcție primește trei argumente: `n` - lungimea listei `v`, `S` - suma căutată și `v` - lista de numere întregi. Scopul funcției este să găsească cea mai lungă subsecvență continuă a listei `v` a cărei sumă este egală cu `S`. Funcția utilizează o abordare dinamică pentru a calcula matricea `dp` care stochează sumele parțiale ale subsecvențelor. Apoi, se verifică fiecare subsecvență pentru a determina cea mai lungă subsecvență cu suma `S`. Funcția returnează un tuplu `(lmax, c)` unde `lmax` este lungimea celei mai lungi subsecvențe și `c` este numărul de subsecvențe cu aceeași lungime maximă.

`validate_input(n, S, v)`: Această funcție primește trei argumente: `n` - lungimea listei `v`, `S` - suma căutată și `v` - lista de numere întregi. Scopul funcției este să valideze datele de intrare conform restricțiilor impuse. Verifică dacă lungimea listei `v` este `n`, dacă `n` se încadrează în intervalul permis și dacă fiecare element din `v` se încadrează în intervalul permis. Returnează `True` dacă datele sunt valide și `False` în caz contrar.

Funcția principală `if __name__ == "__main__"` citeste datele de intrare din fișierul "sumainsecv.in", validează datele folosind funcția `validate_input()`, apoi apelează funcția `secv_suma()` pentru a obține rezultatul dorit. Rezultatul este scris în fișierul "secv10.out". Dacă apar erori în citirea sau validarea datelor, se afișează un mesaj corespunzător pe ecran.