3540 - Ambuscada
Cerința[edit | edit source]
N soldați, numerotați de la 1 la N, sunt prinși într-o ambuscadă. Asupra lor se execută M atacuri de tun. Atacurile afectează nu doar un soldat, ci un interval de soldați, provocând fiecăruia dintre aceștia o anumită pierdere (damage). De exemplu, atacul (3,7,5) afectează soldații 3,4,5,6,7 cu 5 damage. La început, toți soldații au V vieți. Câți soldați rămân în viață după cele M atacuri?
Date de intrare[edit | edit source]
Fișierul de intrare ambuscada.in conține pe prima linie numerele naturale N, M și V separate prin spații. Pe următoarele M linii se află câte 3 numere naturale i j k separate cu un spațiu, cu semnificația de mai sus.
Date de ieșire[edit | edit source]
Fișierul de ieșire ambuscada.out va conține un singur număr natural reprezentând numărul de soldați rămași în viață.
Restricții și precizări[edit | edit source]
- 2 ≤ N ≤ 1.000.000.000, 1 ≤ M ≤ 100.000, 1 ≤ V ≤ 1.000.000.000
- In toate testele, 1 ≤ i ≤ j ≤ N, 1 ≤ k ≤ V
- Pentru teste în valoare de 30 de puncte, N<=100.000 și M<=50
Exemplul 1[edit | edit source]
- ambuscada.in
- 6 4 10
- 2 5 2
- 1 3 7
- 2 6 3
- 3 5 6
- ambuscada.out
- 2
Explicație[edit | edit source]
Inițial toți soldații aveau 10 vieți. După prima tragere: 10 8 8 8 8 10 După a doua tragere: 3 1 1 8 8 10 După a treia tragere: 3 0 0 5 5 7 După a patra tragere: 3 0 0 0 0 7 In final, 2 soldați au rămas în viață: primul și ultimul.
Exemplul 2[edit | edit source]
- ambuscada.in
- 5 2
- 2 7 8
- 1
- ambuscada.out
- Date invalide: Linia 1 nu contine suficiente valori
Rezolvare[edit | edit source]
<syntaxhighlight lang="python" line>
- 3540 Ambuscada
def verificare_date_intrare(N, M, V, atacuri):
# Verificăm dacă N, M și V sunt în intervalul specificat if not (2 <= N <= 1000000000 and 1 <= M <= 100000 and 1 <= V <= 1000000000): return False # Verificăm fiecare atac for atac in atacuri: i, j, k = atac # Verificăm dacă i, j și k sunt în intervalul specificat if not (1 <= i <= j <= N and 1 <= k <= V): return False return True
def soldati_ramasii(N, M, V, atacuri):
# Inițializăm un vector cu viețile soldaților soldati = [V] * N # Parcurgem fiecare atac și actualizăm starea soldaților afectați for atac in atacuri: i, j, k = atac for index in range(i-1, j): soldati[index] -= k # Numărăm câți soldați au vieți pozitive și returnăm rezultatul soldati_ramas = sum(1 for viata in soldati if viata > 0) return soldati_ramas
def main():
# Citim datele de intrare din fișier with open('ambuscada.in', 'r') as f: linii = f.readlines() # Verificăm dacă există suficiente linii în fișierul de intrare if len(linii) < 2: # Scriem mesaj de date invalide în fișierul de ieșire with open('ambuscada.out', 'w') as f: f.write("Date invalide: Nu sunt suficiente date in fisierul de intrare") return # Extragem N, M și V din prima linie try: N, M, V = map(int, linii[0].split()) except ValueError: # Scriem mesaj de date invalide în fișierul de ieșire with open('ambuscada.out', 'w') as f: f.write("Date invalide: Linia 1 nu contine suficiente valori") return # Verificăm dacă există suficiente atacuri în fișierul de intrare if len(linii) - 1 < M: # Scriem mesaj de date invalide în fișierul de ieșire with open('ambuscada.out', 'w') as f: f.write("Date invalide: Nu sunt suficiente atacuri in fisierul de intrare") return # Citim atacurile atacuri = [tuple(map(int, line.split())) for line in linii[1:M+1]] # Verificăm datele de intrare if not verificare_date_intrare(N, M, V, atacuri): # Scriem mesaj de date invalide în fișierul de ieșire with open('ambuscada.out', 'w') as f: f.write("Datele de intrare sunt invalide") return # Calculăm numărul de soldați rămași în viață soldati_ramas = soldati_ramasii(N, M, V, atacuri) # Scriem rezultatul în fișierul de ieșire with open('ambuscada.out', 'w') as f: f.write(str(soldati_ramas))
if __name__ == "__main__":
main()
</syntaxhighlight>