0680 - K Split

From Bitnami MediaWiki

Enunț[edit | edit source]

Se consideră un șir A cu N elemente întregi nenule. Numim secvență a șirului A orice succesiune de elemente aflate pe poziții consecutive în șir: Ai, Ai+1, …, Aj cu 1 ≤ i < j ≤ N. Prin lungimea secvenței înțelegem numărul de elemente care o compun.

Pentru orice secvenţă Ai, Ai+1, …, Aj, vom numi split-point un indice k, i ≤ k < j, care împarte secvența în două subsecvențe nevide: Ai, Ai+1, …, Ak, respectiv Ak+1, Ak+2, …, Aj.

Fie Dmax valoarea absolută maximă a diferenței sumelor elementelor celor două subsecvențe separate de un split-point, luând în considerare toate secvenţele Ai,Ai+1,…,Aj posibile şi fie Lmax lungimea maximă a unei secvenţe caracterizată de valoarea Dmax.

Cerinţă[edit | edit source]

Cunoscând N şi valorile elementelor şirului A, să se determine Dmax şi Lmax.

Date de intrare[edit | edit source]

Fișierul de intrare ksplit.in conține pe prima linie un număr natural N ce reprezintă numărul de elemente al șirului A, iar pe cea de-a doua linie N numere întregi nenule despărțite prin câte un spațiu.

Date de ieșire[edit | edit source]

Fișierul de ieșire ksplit.out va avea două linii. Prima linie conține numărul natural Dmax iar următoarea linie conţine numărul natural Lmax.

Restricții și precizări[edit | edit source]

  • 2 ≤ N ≤ 100 000
  • elementele șirului A sunt numere întregi nenule din intervalul [-1 000 000, 1 000 000]

Exemplu:[edit | edit source]

ksplitin.txt

4

2 3 -1 5

ksplitout.txt

6

3

Explicație[edit | edit source]

Dintre toate secvențele ce se pot forma, se alege secvența 2 3 -1, care este formată din primele 3 elemente ale șirului.

Valoarea Dmax este 6, adică: s1 = 2 + 3 = 5, s2 = -1, Dmax = |5 – (-1)|=6, Lmax = 3.

Se observă că există și secvența -1 5 pentru care : s1 = -1, s2 = 5, Dmax = |-1 – 5|=6 dar această secvență are lungimea 2.

Rezolvare[edit | edit source]

<syntaxhighlight lang="python"> import sys

NMax = 100003

def validate_input(n, a):

   if not (2 <= n <= 100000) or len(a) != n + 1 or any(not (-1000000 <= ai <= 1000000) for ai in a[1:]):
       print("Input invalid. Vă rugăm să verificați restricțiile.")
       return False
   return True

def ssm_st_dr(smax, poz, semn):

   smax[1] = a[1]
   poz[1] = 1
   for i in range(2, n + 1):
       if semn * smax[i - 1] >= 0:
           smax[i] = a[i] + smax[i - 1]
           poz[i] = poz[i - 1]
       else:
           smax[i] = a[i]
           poz[i] = i

def ssm_dr_st(smax, poz, semn):

   smax[n - 1] = a[n]
   poz[n - 1] = n
   for i in range(n - 2, 0, -1):
       if semn * smax[i + 1] >= 0:
           smax[i] = a[i + 1] + smax[i + 1]
           poz[i] = poz[i + 1]
       else:
           smax[i] = a[i + 1]
           poz[i] = i + 1

def sol(smax, smin, pozM, pozm, semn):

   global Max, Lmax
   for i in range(1, n):
       x = semn * (smax[i] - smin[i])
       if x > Max:
           Max = x
           Lmax = semn * (pozM[i] - pozm[i])

if __name__ == "__main__":

   sys.stdin = open("ksplitin.txt", "r")
   sys.stdout = open("ksplitout.txt", "w")
   n = int(input())
   a = [0] + list(map(int, input().split()))
   if not validate_input(n, a):
       sys.exit(1)
   Max = -float('inf')
   smax = [0] * NMax
   smin = [0] * NMax
   pozM = [0] * NMax
   pozm = [0] * NMax
   ssm_st_dr(smax, pozM, 1)
   ssm_dr_st(smin, pozm, -1)
   sol(smax, smin, pozm, pozM, 1)
   ssm_st_dr(smax, pozM, -1)
   ssm_dr_st(smin, pozm, 1)
   sol(smax, smin, pozM, pozm, -1)
   print(f"{Max}\n{Lmax + 1}")

</syntaxhighlight>