0873 - Vase: Difference between revisions

From Bitnami MediaWiki
Andrada378 (talk | contribs)
No edit summary
Andrada378 (talk | contribs)
 
(2 intermediate revisions by the same user not shown)
Line 1: Line 1:
Cerinta
== Cerința ==
Se dau dau două vase cu capacitatea A, respectiv B litri, iniţial goale. Se cere să se măsoare cu ajutorul lor C litri de apă, având la dispoziţie următoarele operaţii:
 
* umplerea completă a unui vas (de la robinet). Operaţia se notează R X, unde X poate fi A sau B.
* golirea completă a unui vas (în chiuvetă). Operaţia se notează X C , unde X poate fi A sau B.
* mutarea dintr-un vas în celălalt. Mutarea din vasul X în vasul Y se încheie când se goleşte vasul X sau când se umple vasul Y. Operaţia se notează X Y, unde X şi Y sunt diferite şi pot fi A sau B.
 
Să se determine o secvenţă de operaţii în urma cărora unul dintre vase să conţină C litri de apă.
 
== Date de intrare ==
Programul citește de la tastatură numerele A B C.


Se dau dau două vase cu capacitatea A, respectiv B litri, iniţial goale. Se cere să se măsoare cu ajutorul lor C litri de apă, având la dispoziţie următoarele operaţii:
== Date de iesire ==
Programul va afișa pe ecran numărul minim de operaţii n, apoi cele n operaţii, fiecare pe o linie. Operaţiile pot fi: R A, R B, A C, B C, A B, B A, cu semnificaţia de mai sus.
 
== Restricții și precizări ==
 
* 1 ≤ A , B , C ≤ 1000
* se garantează că pentru toate datele de test există soluţie
 
=== Exemplu: ===
'''Intrare'''
 
5 8 2
 
'''Ieșire'''
 
4
 
R A
 
A B


umplerea completă a unui vas (de la robinet). Operaţia se notează R X, unde X poate fi A sau B.
R A


golirea completă a unui vas (în chiuvetă). Operaţia se notează X C , unde X poate fi A sau B.
A B


mutarea dintr-un vas în celălalt. Mutarea din vasul X în vasul Y se încheie când se goleşte vasul X sau când se umple vasul Y. Operaţia se notează X Y, unde X şi Y sunt diferite şi pot fi A sau B.
== Explicaţie ==
Vasul A are capacitatea de 5 litri, iar vasul B are capacitatea de 8 litri. Se cere să se măsoare 2 litri de apă.


Să se determine o secvenţă de operaţii în urma cărora unul dintre vase să conţină C litri de apă.
Cele 4 operaţii sunt:


Date de intrare
R A – se umple vasul A. A conţine 5 litri, B conţine 0 litri


Programul citește de la tastatură numerele A B C.
A B – se mută apă din vasul A în B. Se va muta toată apa din A. A conţine 0 litri, B conţine 5 litri


Date de iesire
R A – se umple vasul A. A conţine 5 litri, B conţine 5 litri


Programul va afișa pe ecran numărul minim de operaţii n, apoi cele n operaţii, fiecare pe o linie. Operaţiile pot fi: R A, R B, A C, B C, A B, B A, cu semnificaţia de mai sus.
A B – se mută apă din vasul A în B. Se vor muta 3 litri de apă din A. A conţine 2 litri, B conţine 8 litri


Rezolvare
vasul A conţine 2 litri


def operatii_masurare(A, B, C):
== Rezolvare ==
     operatii = []
<syntaxhighlight lang="python">
def validate_input(A, B, C):
     return 1 <= A <= 1000 and 1 <= B <= 1000 and 1 <= C <= 1000


    def umplere_completa(vas):
# Obțineți valorile de intrare
        if vas == 'A':
A, B, C = map(int, input().split())
            return 'R A'
        else:
            return 'R B'


    def golire_completa(vas):
# Validați valorile de intrare
        if vas == 'A':
if not validate_input(A, B, C):
            return 'A C'
    print("Valorile introduse nu sunt valide. Asigurați-vă că 1 ≤ A, B, C ≤ 1000.")
        else:
            return 'B C'


    def mutare_din_to_A():
v = [-1] * 1000001
        return 'B A'
q = [0] * 1000001
op = [0] * 1000001


     def mutare_din_to_B():
def operatii(poz, cnt):
         return 'A B'
     if poz == 0:
        print(cnt)
    else:
        operatii(v[poz], cnt + 1)
        case = op[poz]
        if case == 1:
            print("A C")
        elif case == 2:
            print("B C")
        elif case == 3:
            print("R A")
        elif case == 4:
            print("R B")
         elif case == 5:
            print("A B")
        elif case == 6:
            print("B A")


    def masoara():
st, dr = 1, 1
        return 'A C'
q[dr] = 0
v[0] = 0
pdr = -1


    def BFS():
while st <= dr and pdr == -1:
        visited = set()
    k = q[st]
        queue = [['', 0, 0]]  # Stare (operație, cantitate_A, cantitate_B)
    x, y = k // 1000, k % 1000


        while queue:
    # Golirea lui A
            state = queue.pop(0)
    xx, yy, kk = 0, y, 0
            if state[1] == C or state[2] == C:
    if v[kk] == -1:
                return state[0].split()
        dr += 1
            if (state[1], state[2]) in visited:
        q[dr] = kk
                continue
        v[kk] = k
             visited.add((state[1], state[2]))
        op[kk] = 1
        if xx == C or yy == C:
             pdr = dr


            # Umplere completă
    # Golirea lui B
            if state[1] < A:
    xx, yy, kk = x, 0, x * 1000
                queue.append([state[0] + umplere_completa('A'), A, state[2]])
    if v[kk] == -1:
            if state[2] < B:
        dr += 1
                queue.append([state[0] + umplere_completa('B'), state[1], B])
        q[dr] = kk
        v[kk] = k
        op[kk] = 2
        if xx == C or yy == C:
            pdr = dr


            # Golire completă
    # Umplerea lui A
            if state[1] > 0:
    xx, yy, kk = A, y, A * 1000 + y
                queue.append([state[0] + golire_completa('A'), 0, state[2]])
    if v[kk] == -1:
            if state[2] > 0:
        dr += 1
                queue.append([state[0] + golire_completa('B'), state[1], 0])
        q[dr] = kk
        v[kk] = k
        op[kk] = 3
        if xx == C or yy == C:
            pdr = dr


            # Mutare între vase
    # Umplerea lui B
            if state[1] > 0 and state[2] < B:
    xx, yy, kk = x, B, x * 1000 + B
                queue.append([state[0] + mutare_din_to_A(), state[1] - min(state[1], B - state[2]), state[2] + min(state[1], B - state[2])])
    if v[kk] == -1:
            if state[2] > 0 and state[1] < A:
        dr += 1
                queue.append([state[0] + mutare_din_to_B(), state[1] + min(state[2], A - state[1]), state[2] - min(state[2], A - state[1])])
        q[dr] = kk
        v[kk] = k
        op[kk] = 4
        if xx == C or yy == C:
            pdr = dr


         return None
    # A -> B
    if y + x <= B:
         yy, xx, kk = y + x, 0, 0
    else:
        yy, xx, kk = B, y + x - B, B * 1000 + (y + x - B)
    if v[kk] == -1:
        dr += 1
        q[dr] = kk
        v[kk] = k
        op[kk] = 5
        if xx == C or yy == C:
            pdr = dr


     rezultat = BFS()
     # B -> A
     return len(rezultat), rezultat
    if x + y <= A:
if __name__ == "__main__":
        xx, yy, kk = x + y, 0, (x + y)
    A = int(input("Capacitatea vasului A: "))
     else:
    B = int(input("Capacitatea vasului B: "))
        xx, yy, kk = A, x + y - A, A * 1000 + (x + y - A)
    C = int(input("Cantitatea dorită de apă: "))
    if v[kk] == -1:
        dr += 1
        q[dr] = kk
        v[kk] = k
        op[kk] = 6
        if xx == C or yy == C:
            pdr = dr


     numar_operatii, secventa_operatii = operatii_masurare(A, B, C)
     st += 1


    print("Numărul minim de operații necesare:", numar_operatii)
if pdr == -1:
     print("Secvența de operații:")
     print("Nu se poate")
    for operatie in secventa_operatii:
else:
        print(operatie)
    operatii(q[pdr], 0)
</syntaxhighlight>

Latest revision as of 16:46, 4 January 2024

Cerința[edit | edit source]

Se dau dau două vase cu capacitatea A, respectiv B litri, iniţial goale. Se cere să se măsoare cu ajutorul lor C litri de apă, având la dispoziţie următoarele operaţii:

  • umplerea completă a unui vas (de la robinet). Operaţia se notează R X, unde X poate fi A sau B.
  • golirea completă a unui vas (în chiuvetă). Operaţia se notează X C , unde X poate fi A sau B.
  • mutarea dintr-un vas în celălalt. Mutarea din vasul X în vasul Y se încheie când se goleşte vasul X sau când se umple vasul Y. Operaţia se notează X Y, unde X şi Y sunt diferite şi pot fi A sau B.

Să se determine o secvenţă de operaţii în urma cărora unul dintre vase să conţină C litri de apă.

Date de intrare[edit | edit source]

Programul citește de la tastatură numerele A B C.

Date de iesire[edit | edit source]

Programul va afișa pe ecran numărul minim de operaţii n, apoi cele n operaţii, fiecare pe o linie. Operaţiile pot fi: R A, R B, A C, B C, A B, B A, cu semnificaţia de mai sus.

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

  • 1 ≤ A , B , C ≤ 1000
  • se garantează că pentru toate datele de test există soluţie

Exemplu:[edit | edit source]

Intrare

5 8 2

Ieșire

4

R A

A B

R A

A B

Explicaţie[edit | edit source]

Vasul A are capacitatea de 5 litri, iar vasul B are capacitatea de 8 litri. Se cere să se măsoare 2 litri de apă.

Cele 4 operaţii sunt:

R A – se umple vasul A. A conţine 5 litri, B conţine 0 litri

A B – se mută apă din vasul A în B. Se va muta toată apa din A. A conţine 0 litri, B conţine 5 litri

R A – se umple vasul A. A conţine 5 litri, B conţine 5 litri

A B – se mută apă din vasul A în B. Se vor muta 3 litri de apă din A. A conţine 2 litri, B conţine 8 litri

vasul A conţine 2 litri

Rezolvare[edit | edit source]

<syntaxhighlight lang="python"> def validate_input(A, B, C):

   return 1 <= A <= 1000 and 1 <= B <= 1000 and 1 <= C <= 1000
  1. Obțineți valorile de intrare

A, B, C = map(int, input().split())

  1. Validați valorile de intrare

if not validate_input(A, B, C):

   print("Valorile introduse nu sunt valide. Asigurați-vă că 1 ≤ A, B, C ≤ 1000.")

v = [-1] * 1000001 q = [0] * 1000001 op = [0] * 1000001

def operatii(poz, cnt):

   if poz == 0:
       print(cnt)
   else:
       operatii(v[poz], cnt + 1)
       case = op[poz]
       if case == 1:
           print("A C")
       elif case == 2:
           print("B C")
       elif case == 3:
           print("R A")
       elif case == 4:
           print("R B")
       elif case == 5:
           print("A B")
       elif case == 6:
           print("B A")

st, dr = 1, 1 q[dr] = 0 v[0] = 0 pdr = -1

while st <= dr and pdr == -1:

   k = q[st]
   x, y = k // 1000, k % 1000
   # Golirea lui A
   xx, yy, kk = 0, y, 0
   if v[kk] == -1:
       dr += 1
       q[dr] = kk
       v[kk] = k
       op[kk] = 1
       if xx == C or yy == C:
           pdr = dr
   # Golirea lui B
   xx, yy, kk = x, 0, x * 1000
   if v[kk] == -1:
       dr += 1
       q[dr] = kk
       v[kk] = k
       op[kk] = 2
       if xx == C or yy == C:
           pdr = dr
   # Umplerea lui A
   xx, yy, kk = A, y, A * 1000 + y
   if v[kk] == -1:
       dr += 1
       q[dr] = kk
       v[kk] = k
       op[kk] = 3
       if xx == C or yy == C:
           pdr = dr
   # Umplerea lui B
   xx, yy, kk = x, B, x * 1000 + B
   if v[kk] == -1:
       dr += 1
       q[dr] = kk
       v[kk] = k
       op[kk] = 4
       if xx == C or yy == C:
           pdr = dr
   # A -> B
   if y + x <= B:
       yy, xx, kk = y + x, 0, 0
   else:
       yy, xx, kk = B, y + x - B, B * 1000 + (y + x - B)
   if v[kk] == -1:
       dr += 1
       q[dr] = kk
       v[kk] = k
       op[kk] = 5
       if xx == C or yy == C:
           pdr = dr
   # B -> A
   if x + y <= A:
       xx, yy, kk = x + y, 0, (x + y)
   else:
       xx, yy, kk = A, x + y - A, A * 1000 + (x + y - A)
   if v[kk] == -1:
       dr += 1
       q[dr] = kk
       v[kk] = k
       op[kk] = 6
       if xx == C or yy == C:
           pdr = dr
   st += 1

if pdr == -1:

   print("Nu se poate")

else:

   operatii(q[pdr], 0)

</syntaxhighlight>