2123 - Relatii: Difference between revisions

From Bitnami MediaWiki
No edit summary
 
(One intermediate revision by the same user not shown)
Line 1: Line 1:
== Enunt ==  
== Enunt ==  


Să considerăm N variabile, denumite cu litere mici ale alfabetului englez, începând cu litera a. Să considerăm de asemenea M relaţii de ordine între aceste N variabile, sub forma:
<code>ar1<var2</code>
var1>var2
sau
var1<var2
unde var1 şi var2 sunt două nume de variabile (deci litere mici distincte dintre primele N litere ale alfabetului englez).


== Cerința ==
unde <code>var1</code> şi <code>var2</code> sunt două nume de variabile (deci litere mici distincte dintre primele <code>N</code> litere ale alfabetului englez).


Scrieţi un program care să ordoneze crescător cele N variabile pe baza celor M relaţii cunoscute.
= Cerința =
Scrieţi un program care să ordoneze crescător cele <code>N</code> variabile pe baza celor <code>M</code> relaţii cunoscute.


== Date de intrare ==
= Date de intrare =
Fişierul de intrare <code>relatiiIN.txt</code> conţine pe prima linie numerele naturale <code>N, M,</code> separate prin spaţiu. Pe fiecare dintre următoarele <code>M</code> linii este scrisă o relaţie sub forma din enunţ.


Fişierul de intrare relatii.in conţine pe prima linie numerele naturale N, M, separate prin spaţiu. Pe fiecare dintre următoarele M linii este scrisă o relaţie sub forma din enunţ.
= Date de ieșire =
Fişierul de ieşire <code>relatiiOUT.txt</code> va conţine o singură linie pe care vor fi scrise <code>N</code> litere mici, neseparate prin spaţii, reprezentând variabilele ordonate crescător. Dacă există mai multe soluţii posibile, se va afişa cea mai mică din punct de vedere lexicografic (prima în dicţionar). În cazul în care restricțiile nu sunt îndeplinite, se va afișa mesajul "Datele nu corespund restrictiilor impuse".


== Date de iesire ==
= Restricții și precizări =
• <code>2 ≤ N ≤ 10</code>


Fişierul de ieşire relatii.out va conţine o singură linie pe care vor fi scrise N litere mici, neseparate prin spaţii, reprezentând variabilele ordonate crescător. Dacă există mai multe soluţii posibile, se va afişa cea mai mică din punct de vedere lexicografic (prima în dicţionar).
• <code>1 ≤ M ≤ 200</code>


== Restricții și precizări ==
Relaţiile specificate în fişierul de intrare nu conţin spaţii.
* 2 ≤ N ≤ 10
* 1 ≤ M ≤ 200
* Relaţiile specificate în fişierul de intrare nu conţin spaţii.
* Pentru datele de test există întotdeauna soluţie, nu neapărat unică.
* Spunem că sirul x1x2...xN este mai mic din punct de vedere lexicografic decât şirul y1y2...yN dacă există un indice k (1≤k≤N) astfel încât xi=yi, pentru orice 1≤i<k şi xk<yk.


== Exemplul 1 ==
• Pentru datele de test există întotdeauna soluţie, nu neapărat unică.


; intrare
• Spunem că sirul <code>x1x2...xN</code> este mai mic din punct de vedere lexicografic decât şirul <code>y1y2...yN</code> dacă există un indice <code>k (1≤k≤N)</code> astfel încât <code>xi=yi</code>, pentru orice <code>1≤i<k</code> şi <code>xk<yk</code>.


:4 5
= Exemplul 1: =
:a<d
<code>relatiiIN.txt</code>
:a<c
4 5
:c>d
a<d
:b>c
a<c
:b>a
c>d
b>c
b>a
<code>relatiiOUT.txt</code>
adcb


; iesire
== Exemplul 2: ==
 
<code>relatiiIN.txt</code>
:Datele introduse corespund rectrictiilor impuse.
4 5
 
a<d
:adcb
a<c
 
c>d
== Exemplul 2 ==  
b>c
 
b>a
; intrare
<code>relatiiOUT.txt</code>
 
Datele nu corespund restrictiilor impuse.
:10 3
 
:b>a
 
:c>a
 
:a<b
 
:d>c
 
:c>d
 
; iesire
 
:Datele de intrare nu corespund restrictiilor impuse.


== Rezolvare ==
== Rezolvare ==
<syntaxhighlight lang="python3" line="1">
<syntaxhighlight lang="python3" line="1">
def verificare_restrictii(N, M):
    if not (2 <= N <= 10 and 1 <= M <= 200):
        with open("relatiiOUT.txt", "w") as fout:
            fout.write("Datele nu corespund restrictiilor impuse.\n")
        return False
    return True


#2123 - Relatii
def citire():
 
    with open("relatiiIN.txt", "r") as file:
from collections import defaultdict
        first_line = file.readline().strip()
 
        if not first_line:
def ordonare_crescatoare(N, relatii):
            return None, None
    graf = defaultdict(list)
        N, M = map(int, first_line.split())
    indegree = {chr(ord('a') + i): 0 for i in range(N)}
        if not verificare_restrictii(N, M):
 
            return None, None
    # Construirea grafului și calcularea gradelor de intrare
        R = [[0] * (N + 1) for _ in range(N + 1)]
    for relatie in relatii:
        for _ in range(M):
        var1, semn, var2 = relatie
            line = file.readline().strip()
        graf[var1].append(var2)
            if not line:
        indegree[var2] += 1
              return None, None
 
            c1, c2, c3 = line[0], line[1], line[2]
    # Sortare topologică
            if c2 == '<':
    ordine_topologica = []
                R[ord(c1) - ord('a') + 1][ord(c3) - ord('a') + 1] = -1
    stiva = [var for var, grad in indegree.items() if grad == 0]
                R[ord(c3) - ord('a') + 1][ord(c1) - ord('a') + 1] = 1
 
            else:
    while stiva:
                R[ord(c1) - ord('a') + 1][ord(c3) - ord('a') + 1] = 1
        nod = stiva.pop()
                R[ord(c3) - ord('a') + 1][ord(c1) - ord('a') + 1] = -1
        ordine_topologica.append(nod)
    return N, R


         for vecin in graf[nod]:
def afisare(p):
             indegree[vecin] -= 1
    with open("relatiiOUT.txt", "w") as fout:
            if indegree[vecin] == 0:
         for i in range(1, len(p)):
                stiva.append(vecin)
             fout.write(chr(p[i] - 1 + ord('a')))
        fout.write('\n')


    # Verificare dacă există un ciclu (graful nu este aciclic)
def verif(p, R):
     if len(ordine_topologica) != N:
     for i in range(1, len(p)):
         print("Ordin imposibil. Graful contine un ciclu.")
         for j in range(i + 1, len(p)):
        return None
            if R[p[i]][p[j]] == 1:
                return False
    return True


     return ordine_topologica
def main():
     N, R = citire()
    if N is None or R is None:
        return  
    p = list(range(N + 1))
    while True:
        if verif(p, R):
            break
        j = N - 1
        while p[j] > p[j + 1]:
            j -= 1
        i = N
        while p[i] < p[j]:
            i -= 1
        p[i], p[j] = p[j], p[i]
        st, dr = j + 1, N
        while st < dr:
            p[st], p[dr] = p[dr], p[st]
            st += 1
            dr -= 1
    afisare(p)


rezultat = ordonare_crescatoare(N, relatii)
if __name__ == "__main__":
    main()


if rezultat:
    print("Ordine crescatoare a variabilelor:", rezultat)
</syntaxhighlight>
</syntaxhighlight>

Latest revision as of 11:23, 23 February 2024

Enunt[edit | edit source]

ar1<var2

unde var1 şi var2 sunt două nume de variabile (deci litere mici distincte dintre primele N litere ale alfabetului englez).

Cerința[edit | edit source]

Scrieţi un program care să ordoneze crescător cele N variabile pe baza celor M relaţii cunoscute.

Date de intrare[edit | edit source]

Fişierul de intrare relatiiIN.txt conţine pe prima linie numerele naturale N, M, separate prin spaţiu. Pe fiecare dintre următoarele M linii este scrisă o relaţie sub forma din enunţ.

Date de ieșire[edit | edit source]

Fişierul de ieşire relatiiOUT.txt va conţine o singură linie pe care vor fi scrise N litere mici, neseparate prin spaţii, reprezentând variabilele ordonate crescător. Dacă există mai multe soluţii posibile, se va afişa cea mai mică din punct de vedere lexicografic (prima în dicţionar). În cazul în care restricțiile nu sunt îndeplinite, se va afișa mesajul "Datele nu corespund restrictiilor impuse".

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

2 ≤ N ≤ 10

1 ≤ M ≤ 200

• Relaţiile specificate în fişierul de intrare nu conţin spaţii.

• Pentru datele de test există întotdeauna soluţie, nu neapărat unică.

• Spunem că sirul x1x2...xN este mai mic din punct de vedere lexicografic decât şirul y1y2...yN dacă există un indice k (1≤k≤N) astfel încât xi=yi, pentru orice 1≤i<k şi xk<yk.

Exemplul 1:[edit | edit source]

relatiiIN.txt

4 5
a<d
a<c
c>d
b>c
b>a

relatiiOUT.txt

adcb

Exemplul 2:[edit | edit source]

relatiiIN.txt

4 5
a<d
a<c
c>d
b>c
b>a

relatiiOUT.txt

Datele nu corespund restrictiilor impuse.

Rezolvare[edit | edit source]

<syntaxhighlight lang="python3" line="1"> def verificare_restrictii(N, M):

   if not (2 <= N <= 10 and 1 <= M <= 200):
       with open("relatiiOUT.txt", "w") as fout:
           fout.write("Datele nu corespund restrictiilor impuse.\n")
       return False
   return True

def citire():

   with open("relatiiIN.txt", "r") as file:
       first_line = file.readline().strip()
       if not first_line:
           return None, None
       N, M = map(int, first_line.split())
       if not verificare_restrictii(N, M):
           return None, None
       R = [[0] * (N + 1) for _ in range(N + 1)]
       for _ in range(M):
           line = file.readline().strip()
           if not line:
              return None, None
           c1, c2, c3 = line[0], line[1], line[2]
           if c2 == '<':
               R[ord(c1) - ord('a') + 1][ord(c3) - ord('a') + 1] = -1
               R[ord(c3) - ord('a') + 1][ord(c1) - ord('a') + 1] = 1
           else:
               R[ord(c1) - ord('a') + 1][ord(c3) - ord('a') + 1] = 1
               R[ord(c3) - ord('a') + 1][ord(c1) - ord('a') + 1] = -1
   return N, R

def afisare(p):

   with open("relatiiOUT.txt", "w") as fout:
       for i in range(1, len(p)):
           fout.write(chr(p[i] - 1 + ord('a')))
       fout.write('\n')

def verif(p, R):

   for i in range(1, len(p)):
       for j in range(i + 1, len(p)):
           if R[p[i]][p[j]] == 1:
               return False
   return True

def main():

   N, R = citire()
   if N is None or R is None:
       return 
   p = list(range(N + 1))
   while True:
       if verif(p, R):
           break
       j = N - 1
       while p[j] > p[j + 1]:
           j -= 1
       i = N
       while p[i] < p[j]:
           i -= 1
       p[i], p[j] = p[j], p[i]
       st, dr = j + 1, N
       while st < dr:
           p[st], p[dr] = p[dr], p[st]
           st += 1
           dr -= 1
   afisare(p)

if __name__ == "__main__":

   main()

</syntaxhighlight>