0677 - Nivele Bin: Difference between revisions

From Bitnami MediaWiki
Pagină nouă: == Cerința == Considerăm un arbore binar cu n noduri în care fiecare nod este numerotat de la 1 la n și conține o valoare număr natural. În acest arbore rădăcina este considerată pe nivelul 0, descendenții direcți ai rădăcinii pe nivelul 1, etc. Să se determine numărul de nivele k din arbore și, pentru fiecare nivel i de la 0 la k, numărul de noduri situate pe acel nivel. == Date de intrare == Fișierul de intrare nivelebinin.txt conține pe prima linie num...
 
No edit summary
Line 1: Line 1:
== Cerința ==
= Cerința =
Considerăm un arbore binar cu n noduri în care fiecare nod este numerotat de la 1 la n și conține o valoare număr natural. În acest arbore rădăcina este considerată pe nivelul 0, descendenții direcți ai rădăcinii pe nivelul 1, etc. Să se determine numărul de nivele k din arbore și, pentru fiecare nivel i de la 0 la k, numărul de noduri situate pe acel nivel.
Considerăm un arbore binar cu <code>n</code> noduri în care fiecare nod este numerotat de la <code>1</code> la <code>n</code> și conține o valoare număr natural. În acest arbore rădăcina este considerată pe nivelul <code>0</code>, descendenții direcți ai rădăcinii pe nivelul <code>1</code>, etc. Să se determine numărul de nivele <code>k</code> din arbore și, pentru fiecare nivel <code>i</code> de la <code>0</code> la <code>k</code>, numărul de noduri situate pe acel nivel.
== Date de intrare ==
Fișierul de intrare nivelebinin.txt conține pe prima linie numărul n. Fiecare dintre următoarele n linii conține câte 3 numere X st dr; linia i + 1 din fișier conține informațiile despre nodul numerotat cu i: X reprezintă valoare din nod, st reprezintă numărul de ordine al descendentului stâng sau 0 dacă nodul i nu are descendent stâng, iar dr reprezintă numărul de ordine al descendentului drept sau 0 dacă nodul i nu are descendent drept.
== Date de ieșire ==
Fișierul de ieșire nivelebinout.txt va conține pe prima linie numărul k, iar pe a doua linie k+1 numere naturale separate prin exact un spațiu, al i-lea număr reprezentând numărul de noduri situate pe nivelul i-1 din arbore.
== Restricții și precizări ==
*'''1 ≤ n ≤ 1000'''
*valorile din nodurile arborelui vor fi mai mici sau egale cu 1.000.000
== Exemplul 1 ==
; nivelebinin.txt
: 6
: 2 3 5
: 6 0 6
: 1 0 0
: 7 1 2
: 4 0 0
: 10 0 0
; nivelebinout.txt
: 3
: 1 2 3
<br>
== Exemplul 2 ==
; nivelebinin.txt
: 7
: 1 2 3
: 2 4 0
: 3 5 6
: 4 0 0
: 5 7 0
: 6 0 0
: 7 0 0
; nivelebinout.txt
: 3
: 1 2 4
<br>
== Rezolvare ==
<syntaxhighlight lang="python" line>
#0677 - Nivele Bin
class TreeNode:
    def __init__(self, value, left=None, right=None):
        self.value = value
        self.left = left
        self.right = right


def read_tree_from_file(file):
= Date de intrare =
    n = int(file.readline())
Fișierul de intrare <code>nivelebinIN.txt</code> conține pe prima linie numărul <code>n</code>. Fiecare dintre următoarele <code>n</code> linii conține câte <code>3</code> numere <code>X st dr</code>; linia <code>i + 1</code> din fișier conține informațiile despre nodul numerotat cu <code>i</code>: <code>X</code> reprezintă valoare din nod, <code>st</code> reprezintă numărul de ordine al descendentului stâng sau <code>0</code> dacă nodul <code>i</code> nu are descendent stâng, iar <code>dr</code> reprezintă numărul de ordine al descendentului drept sau <code>0</code> dacă nodul <code>i</code> nu are descendent drept.
    if not (1 <= n <= 1000):
        return None


    nodes = [None]  # index 0 nu este folosit
= Date de ieșire =
Fișierul de ieșire <code>nivelebinOUT.txt</code> va conține pe prima linie numărul <code>k</code>, iar pe a doua linie <code>k+1</code> numere naturale separate prin exact un spațiu, al <code>i</code>-lea număr reprezentând numărul de noduri situate pe nivelul <code>i-1</code> din arbore.


    for i in range(1, n + 1):
= Restricții și precizări =
        x, st, dr = map(int, file.readline().split())
        if not (1 <= x <= 1000000):
            return None
        if not (0 <= st <= n):
            return None
        if not (0 <= dr <= n):
            return None
        nodes.append(TreeNode(x, st, dr))


    return nodes
* <code>1 ≤ n ≤ 1000</code>
* valorile din nodurile arborelui vor fi mai mici sau egale cu <code>1.000.000</code>


def calculate_levels_and_counts(root, nodes):
= Exemplul 1: =
    levels_counts = {}
<code>nivelebinIN.txt</code>
    stack = [(root, 0)] # Stivă de noduri și niveluri
6
2 3 5
6 0 6
1 0 0
7 1 2
4 0 0
10 0 0
<code>nivelebinOUT.txt</code>
3
  1 2 3


    while stack:
= Explicație =
        node, level = stack.pop()
Exemplul corespunde arborelui de mai jos, în care au fost marcate cu albastru valorile din noduri, iar cu roșu numerele de ordine ale nodurilor.


        if level not in levels_counts:
Arborele conține trei nivele:
            levels_counts[level] = 1
        else:
            levels_counts[level] += 1


        if nodes[node].left:
* nivelul <code>0</code> conține doar rădăcina, nodul numerotat cu <code>4</code>
            stack.append((nodes[node].left, level + 1))
* nivelul <code>1</code> conține două noduri, cele numerotate cu <code>1 2</code>
        if nodes[node].right:
* nivelul <code>2</code> conține trei noduri, cele numerotate cu <code>3 5 6</code>
            stack.append((nodes[node].right, level + 1))


    return levels_counts
== Exemplul 2: ==
<code>nivelebinIN.txt</code>
1001
2 3 5
6 0 6
1 0 0
7 1 2
4 0 0
10 0 0
<code>nivelebinOUT.txt</code>
Datele nu corespund restrictiilor impuse


def check_restrictions(n):
== Rezolvare ==
     return 1 <= n <= 1000
<syntaxhighlight lang="python" line="1">
def completniv(k, niv, nivele, s, d):
    if k != 0:
        nivele[k] = niv
        completniv(s[k], niv + 1, nivele, s, d)
        completniv(d[k], niv + 1, nivele, s, d)
 
def verifica_restrictii(n, noduri):
     if not (1 <= n <= 1000):
        return False
    for x, s, d in noduri:
        if x > 1000000 or s > 1000000 or d > 1000000:
            return False
    return True


def main():
def main():
     with open('nivelebinin.txt', 'r') as file:
     try:
        n = int(file.readline())
        with open("nivelebinIN.txt", "r") as fin:
        if not check_restrictions(n):
            n = int(fin.readline().strip())
            print("false")
            noduri = [tuple(map(int, fin.readline().strip().split())) for _ in range(n)]
            return
 
            if not verifica_restrictii(n, noduri):
                raise ValueError("Datele nu corespund restrictiilor impuse")


        nodes = read_tree_from_file(file)
            s = [0] * (n + 1)
        if nodes is None:
            d = [0] * (n + 1)
             print("false")
            p = [0] * (n + 1)
             return
             nivele = [0] * (n + 1)
              
            for i in range(1, n + 1):
                x, s[i], d[i] = noduri[i-1]
                p[s[i]] = 1
                p[d[i]] = 1


        root = 1  # Rădăcina arborelui
            r = 0
        levels_counts = calculate_levels_and_counts(root, nodes)
            for i in range(1, n + 1):
                if p[i] == 0:
                    r = i
                    break


        k = len(levels_counts) - 1  # Numărul de niveluri
            completniv(r, 0, nivele, s, d)
        counts_list = [levels_counts[i] for i in range(k + 1)]
           
            nivmax = max(nivele)


    with open('nivelebinout.txt', 'w') as file:
            with open("nivelebinOUT.txt", "w") as fout:
        file.write(str(k) + '\n')
                fout.write(f"{nivmax + 1}\n")
        file.write(' '.join(map(str, counts_list)))
                for niv in range(nivmax + 1):
                    k = sum(1 for j in range(1, n + 1) if nivele[j] == niv)
                    fout.write(f"{k} ")
 
    except ValueError as e:
        with open("nivelebinOUT.txt", "w") as fout:
            fout.write(str(e))


if __name__ == "__main__":
if __name__ == "__main__":
Line 111: Line 106:


</syntaxhighlight>
</syntaxhighlight>
== Explicatie ==
Exemplul corespunde arborelui de mai jos, în care au fost marcate cu albastru valorile din noduri, iar cu roșu numerele de ordine ale nodurilor.
<br>
Arborele conține trei nivele:
*nivelul 0 conține doar rădăcina, nodul numerotat cu 4
*nivelul 1 conține două noduri, cele numerotate cu 1 2
*nivelul 2 conține trei noduri, cele numerotate cu 3 5 6

Revision as of 14:23, 18 May 2024

Cerința

Considerăm un arbore binar cu n noduri în care fiecare nod este numerotat de la 1 la n și conține o valoare număr natural. În acest arbore rădăcina este considerată pe nivelul 0, descendenții direcți ai rădăcinii pe nivelul 1, etc. Să se determine numărul de nivele k din arbore și, pentru fiecare nivel i de la 0 la k, numărul de noduri situate pe acel nivel.

Date de intrare

Fișierul de intrare nivelebinIN.txt conține pe prima linie numărul n. Fiecare dintre următoarele n linii conține câte 3 numere X st dr; linia i + 1 din fișier conține informațiile despre nodul numerotat cu i: X reprezintă valoare din nod, st reprezintă numărul de ordine al descendentului stâng sau 0 dacă nodul i nu are descendent stâng, iar dr reprezintă numărul de ordine al descendentului drept sau 0 dacă nodul i nu are descendent drept.

Date de ieșire

Fișierul de ieșire nivelebinOUT.txt va conține pe prima linie numărul k, iar pe a doua linie k+1 numere naturale separate prin exact un spațiu, al i-lea număr reprezentând numărul de noduri situate pe nivelul i-1 din arbore.

Restricții și precizări

  • 1 ≤ n ≤ 1000
  • valorile din nodurile arborelui vor fi mai mici sau egale cu 1.000.000

Exemplul 1:

nivelebinIN.txt

6
2 3 5
6 0 6
1 0 0
7 1 2
4 0 0
10 0 0

nivelebinOUT.txt

3
1 2 3

Explicație

Exemplul corespunde arborelui de mai jos, în care au fost marcate cu albastru valorile din noduri, iar cu roșu numerele de ordine ale nodurilor.

Arborele conține trei nivele:

  • nivelul 0 conține doar rădăcina, nodul numerotat cu 4
  • nivelul 1 conține două noduri, cele numerotate cu 1 2
  • nivelul 2 conține trei noduri, cele numerotate cu 3 5 6

Exemplul 2:

nivelebinIN.txt

1001
2 3 5
6 0 6
1 0 0
7 1 2
4 0 0
10 0 0

nivelebinOUT.txt

Datele nu corespund restrictiilor impuse

Rezolvare

<syntaxhighlight lang="python" line="1"> def completniv(k, niv, nivele, s, d):

   if k != 0:
       nivele[k] = niv
       completniv(s[k], niv + 1, nivele, s, d)
       completniv(d[k], niv + 1, nivele, s, d)

def verifica_restrictii(n, noduri):

   if not (1 <= n <= 1000):
       return False
   for x, s, d in noduri:
       if x > 1000000 or s > 1000000 or d > 1000000:
           return False
   return True

def main():

   try:
       with open("nivelebinIN.txt", "r") as fin:
           n = int(fin.readline().strip())
           noduri = [tuple(map(int, fin.readline().strip().split())) for _ in range(n)]
           if not verifica_restrictii(n, noduri):
               raise ValueError("Datele nu corespund restrictiilor impuse")
           s = [0] * (n + 1)
           d = [0] * (n + 1)
           p = [0] * (n + 1)
           nivele = [0] * (n + 1)
           
           for i in range(1, n + 1):
               x, s[i], d[i] = noduri[i-1]
               p[s[i]] = 1
               p[d[i]] = 1
           r = 0
           for i in range(1, n + 1):
               if p[i] == 0:
                   r = i
                   break
           completniv(r, 0, nivele, s, d)
           
           nivmax = max(nivele)
           with open("nivelebinOUT.txt", "w") as fout:
               fout.write(f"{nivmax + 1}\n")
               for niv in range(nivmax + 1):
                   k = sum(1 for j in range(1, n + 1) if nivele[j] == niv)
                   fout.write(f"{k} ")
   except ValueError as e:
       with open("nivelebinOUT.txt", "w") as fout:
           fout.write(str(e))

if __name__ == "__main__":

   main()

</syntaxhighlight>