0297 - SecvSumMax: Difference between revisions

From Bitnami MediaWiki
Flaviu (talk | contribs)
No edit summary
Flaviu (talk | contribs)
No edit summary
Line 10: Line 10:


== Date de ieșire ==  
== Date de ieșire ==  
Fișierul de ieșire secvsummax.out va conține pe prima linie numerele p și u, separate printr-un spațiu, reprezentând poziția de început și de sfârșit a secvenței determinate.
Fișierul de ieșire secvsummax.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 c''', 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 22: Line 24:
: -4 1 -5 1 4 -2 2 3 -4 4
: -4 1 -5 1 4 -2 2 3 -4 4
; Ieșire
; Ieșire
: Datele nu corespund restricțiilor impuse.
: Datele sunt introduse correct.
: 4 8
: 4 8


Line 30: Line 34:


def citire():
def citire():
     n = int(input())
     try:
    a = []
        n = int(input())
    for i in range(n):
        a = []
        a.extend(list(map(int, input().split())))
        for i in range(n):
     return a
            a.extend(list(map(int, input().split())))
        return a
     except:
        print("Datele nu corespund restricțiilor impuse.")
        return []


def secvsummax(a):
def secvsummax(a):
Line 57: Line 65:
if __name__ == "__main__":
if __name__ == "__main__":
     a = citire()
     a = citire()
     start, end = secvsummax(a)
     if a:
    if validare(a, start, end):
        start, end = secvsummax(a)
        print(start, end)
        if validare(a, start, end):
            print("Datele sunt introduse corect.")
            print(start, end)
        else:
            print("Datele nu corespund restricțiilor impuse.")
     else:
     else:
         print("Eroare")
         print("Datele nu corespund restricțiilor impuse.")





Revision as of 14:32, 28 April 2023

Sursa: 0297 - SecvSumMax


Cerinţa

Se dă un șir cu n elemente, numere întregi. Determinați secvența de elemente cu suma maximă.


Date de intrare

Fișierul de intrare secvsummax.in conține pe prima linie numărul n; urmează cele n elemente ale șirului, dispuse pe mai multe linii și separate prin spații.


Date de ieșire

Fișierul de ieșire secvsummax.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 c, 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 ≤ 100.000
  • elementele șirului vor avea cel mult 4 cifre și sunt numerotate de la 1 la n
  • dacă șirul conține mai multe secvențe de suma maximă, se va determina cea cu indicele de început cel mai mic, iar în caz de egalitate, cea mai scurtă
  • șirul va conține cel puțin un element pozitiv

Exemplu

Intrare
10
-4 1 -5 1 4 -2 2 3 -4 4
Ieșire
Datele nu corespund restricțiilor impuse.
Datele sunt introduse correct.
4 8

Rezolvare

Rezolvare ver. 1

<syntaxhighlight lang="python" line>

  1. 0297 - SecvSumMax

def citire():

   try:
       n = int(input())
       a = []
       for i in range(n):
           a.extend(list(map(int, input().split())))
       return a
   except:
       print("Datele nu corespund restricțiilor impuse.")
       return []

def secvsummax(a):

   max_sum = a[0]
   start, end = 0, 0
   curr_sum = a[0]
   curr_start = 0
   for i in range(1, len(a)):
       if curr_sum < 0:
           curr_sum = a[i]
           curr_start = i
       else:
           curr_sum += a[i]
       if curr_sum > max_sum or (curr_sum == max_sum and i - curr_start < end - start):
           max_sum = curr_sum
           start, end = curr_start, i
   return start+1, end+1

def validare(a, start, end):

   return sum(a[start-1:end]) == max(sum(a[i:j]) for i in range(len(a)) for j in range(i+1,len(a)+1))

if __name__ == "__main__":

   a = citire()
   if a:
       start, end = secvsummax(a)
       if validare(a, start, end):
           print("Datele sunt introduse corect.")
           print(start, end)
       else:
           print("Datele nu corespund restricțiilor impuse.")
   else:
       print("Datele nu corespund restricțiilor impuse.")


</syntaxhighlight>

Explicatie Rezolvare

Pentru a rezolva această problemă putem folosi algoritmul Kadane, care constă în a parcurge șirul și a calcula suma maximă a unei subsecvențe care se termină la fiecare element. De asemenea, menținem și pozițiile de început și sfârșit ale acestei subsecvențe. La fiecare pas, dacă suma calculată este mai mare decât suma maximă anterioră, actualizăm pozițiile de început și sfârșit ale subsecvenței cu suma maximă. La final, returnăm aceste poziții. Funcția citire citește datele de intrare, formate din n următoarele linii, fiecare conținând o valoare din șir. Lista a este construită prin extinderea sub-listelor formate din aceste valori.

Funcția secvsummax primește lista a și returnează pozițiile de început și sfârșit ale subsecvenței cu suma maximă, conform algoritmului Kadane.

Funcția validare primește lista a și pozițiile de început și sfârșit ale unei subsecvențe și returnează True dacă această subsecvență are suma maximă și False în caz contrar.

În funcția principală, se apelează funcția citire, apoi se determină subsecvența cu suma maximă cu ajutorul funcției secvsummax. Dacă această subsecvență este validă, se afișează pozițiile de început și sfârșit, altfel se afișează "Eroare".