3437 - Datorii 1

From Bitnami MediaWiki

Într-o țară îndepărtată, economia este în criză. Cea mai mare problemă este lipsa de capital care creează blocaje financiare. De exemplu, o firmă X poate avea datorii către o firmă Y pe care nu le poate plăti, deoarece o altă firmă Z are datorii către firma X pe care nu le-a plătit, ş.a.m.d. Există o listă cu toate datoriile firmelor sub forma următoare: X > Y S cu semnificaţia “firma X datorează firmei Y' suma S”. Este posibil ca X să aibă mai multe datorii la firma Y (în funcţie de contractele derulate împreună) sau chiar ca X să aibă datorii la Y și Y să aibă datorii la X.

Cerințe[edit | edit source]

Cunoscând lista cu datoriile firmelor, scrieți un program care să rezolve următoarele cerințe: 1. determină numărul de firme distincte care apar în această listă; 2. realizează o situație financiară a firmelor distincte din această listă, scrise în ordine lexicografică; pentru fiecare firmă se vor determina două valori SD SP, unde SD reprezintă suma totală a datoriilor pe care firma le are către alte firme, iar SP este totalul sumelor pe care firma trebuie să le primească de la alte firme.

Date de intrare[edit | edit source]

Fișierul de intrare datorii1in.txt conține pe prima linie un număr natural C reprezentând cerința care trebuie să fie rezolvată (1 sau 2). Pe a doua linie se află un număr natural D care reprezintă numărul de înregistrări existente în lista datoriilor firmelor. Pe următoarele D linii sunt descrise datoriile firmelor, în forma specificată în enunț, câte o datorie pe o linie.

Date de ieșire[edit | edit source]

Fișierul de ieșire datoriiout.txt va conține răspunsul la cerinţa C specificată în fișierul de intrare. Dacă C=1 fișierul va conține un număr natural, reprezentând numărul de firme distincte care apar în lista menționată. Dacă C=2 fișierul va conține pentru fiecare dintre firmele distincte din lista menționată câte un singur triplet de forma X SD SP, unde X este numele firmei, iar SD și SP au semnificația din enunț pentru firma X; tripletele vor fi scrise astfel încât numele firmelor să apară în ordine lexicografică, fiecare triplet pe câte o linie a fișierului, iar X, SD și SP vor fi separate prin câte un singur spațiu.

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

  • Există în total cel mult 6000 de firme distincte în lista menționată de datorii.
  • Numele unei firme este format din maximum 20 de caractere (litere mari şi mici ale alfabetului englez, cifre, spaţii); se face distincţie între literele mari şi literele mici în numele firmelor; nu există alte restricţii referitoare la numele firmelor.
  • Două firme distincte au nume distincte. O firmă nu poate avea datorii la ea însăși.
  • În descrierea unei datorii (X > Y S) există un singur spaţiu între X și >, un singur spațiu între > și Y, respectiv un singur spațiu între Y și S.
  • 1 ≤ D ≤ 80000
  • Sumele datorate de firme sunt numere naturale nenule ≤106.
  • Dacă X și Y sunt numele a două firme distincte, iar k (k≥0) este valoarea maximă cu proprietatea că secvența formată din primele k caractere din X este identică cu secvența formată din primele caractere din Y, spunem că X precedă din punct de vedere lexicografic pe Y dacă X are doar k caractere sau dacă al k+1-lea caracter din X este mai mic decât al k+1-lea caracter din Y.
  • Pentru teste valorând 30 de puncte cerinţa este 1. Pentru teste valorând 60 de puncte cerinţa este 2.
  • Pentru teste valorând 40 de puncte D≤1000. Pentru teste valorând 45 de puncte numele firmelor nu

conțin spaţii.

  • În concurs s-au acordat 10 puncte din oficiu. Pe site se acordă 10 puncte pentru exemple.

Exemplul 1[edit | edit source]

datoriiin.txt
1
4
Vasile Inc > Anatolia 100
ana > Anatolia 10
ana > Vasilescu Inc 5
Popa25 PF > Anatolia 30
datoriiout.txt
Datele introduse corespund restricțiilor impuse.
5

Exemplul 2[edit | edit source]

datoriiin.txt
2
5
Vasile Inc > Anatolia 100
ana > Anatolia 10
ana > Vasilescu Inc 5
Popa25 PF > Anatolia 30
Popa25 PF > ana 50
datoriiout.txt
Datele introduse corespund restricțiilor impuse.
Anatolia 0 140
Popa25 PF 80 0
Vasile Inc 100 0
Vasilescu Inc 0 5
ana 15 50

Exemplul 3[edit | edit source]

datoriiin.txt
2
6
Vasile Inc > Anatolia 100
ana > Anatolia 10
ana > Vasilescu Inc 5
Popa25 PF > Anatolia 30
Popa25 PF > ana 50
Vasile Inc > Vasile Inc 20
datoriiout.txt
Datele introduse nu corespund restricțiilor impuse.

Rezolvare[edit | edit source]

<syntaxhighlight lang="python" line="1">

  1. 3437 - Datorii 1

from collections import defaultdict


def validare(datorii_val1): # functia de validare a datelor de intrare

   if len(datorii_val1) > 6000:
       raise ValueError
   for X_val1, Y_val1, S_val1 in datorii_val1:
       if len(X_val1) > 20 or len(Y_val1) > 20 or S_val1 <= 0 or S_val1 > 10**6:
           raise ValueError
   file_out.write("Datele de intrare corespund restrictiilor impuse\n")


def rezolvare(datorii_val1): # functia de rezolvare

   firme = defaultdict(lambda: [0, 0])  # dictionar cu valori default [0, 0]
   for X_val1, Y_val1, S_val1 in datorii_val1:
       firme[X_val1][0] += S_val1  # adaugam la suma datoriilor firmei X
       firme[Y_val1][1] += S_val1  # adaugam la suma pe care firma Y trebuie sa o primeasca
   for firma in sorted(firme.keys()):  # sortam firmele lexicografic
       file_out.write(f"{firma} {firme[firma][0]} {firme[firma][1]}\n")


if __name__ == '__main__':

   file_in = open("datoriiin.txt", "r")         # declararea fisierelor
   file_out = open("datoriiout.txt", "w")       # fisierul out trebuie declarat cu optiunea "w" (write)
   # din cauza datelor de intrare pot aparea 2 tipuri de erori, valueError sau IndexError pe care le tratam
   try:
       C = int(file_in.readline())      # citirea cerintei
       D = int(file_in.readline())      # citirea numarului de datorii
       datorii_val = []
       for _ in range(D):
           X_val, _, Y_val, S_val = file_in.readline().split()
           S_val = int(S_val)
           datorii_val.append((X_val, Y_val, S_val))
       validare(datorii_val)                 # apelul functiei de validare
       if C == 2:
           rezolvare(datorii_val)             # apelul functiei de rezolvare
   except ValueError:
       file_out.write("Datele de intrare nu corespund restrictiilor impuse")
   except IndexError:
       file_out.write("Datele de intrare nu corespund restrictiilor impuse")

</syntaxhighlight>