3550 - liceu

De la Universitas MediaWiki

Cerința

Marciuc este un băiat foarte neastâmpărat. El refuză să învețe informatică, așa că înainte de fiecare oră el pleacă pentru a explora noul său liceu. La plecare le promite colegilor lui că o să treacă pe la magazin înainte de a se întoarce în clasă, pentru a avea ce să mănânce în pauza următoare. Însă, dacă va ajunge în clasă în mai mult de T secunde, va întarza la ora așa că în acest caz va folosi o ruta directă spre clasă.

Liceul poate fi reprezentat sub forma unei matrice cu n linii și n coloane. Există 3 tipuri de celule:

  • celulă liberă, pe unde băiatul poate avansa, o mutare durând o secundă;
  • celulă ocupată de un zid, pe unde băiatul nu poate avansa;
  • celulă în care se află o scurtătură, ce îl duce într-o secundă de la poziția, x1 y1, la poziția x2 y2 sau invers;

Fiind dat numărul n de linii și de coloane, coordonatele celulelor ocupate de zid și coordonatele scurtăturilor, se cere să se afișeze numărul minim de secunde în care Marciuc reușește să ajungă în clasă, trecând și pe la magazin. Dacă magazinul nu este accesibil sau daca va ajunge în clasă in mai mult de T secunde, atunci el nu va mai merge la magazin și se va afișa numărul minim de secunde în care acesta ajunge de la poziția lui la clasă. De asemenea, se va afișa și traseul folosit.

Date de intrare

Pe prima linie a fișierului liceu.in se vor afla 4 numere naturale: n – numărul de linii și de coloane ale matricei, z – numărul de ziduri ce blochează calea băiatului, s – numărul de scurtături și t – numărul de secunde în care Marciuc poate ajunge în clasă dacă vrea să treacă și pe la magazin.

Pe următoarele Z linii se află câte 2 numere reprezentânt coordonatele celulelor ocupate de zid.

Pe următoarele S linii se află câte 4 numere naturale reprezentând coordonatele a două celule ce formează o scurtătură.

Pe ultima linie se află 2 numere ce reprezintă coordonatele magazinului.

Date de ieșire

Fișierul de ieșire liceu.out va conține pe prima linie numărul minim de secunde în care băiatul ajunge în clasă, iar pe următoarele linii traseul complet al băiatului, celule fiind afișate în ordinea parcurgerii.

Restricții și precizări

  • 1 ≤ n ≤ 400
  • 5 ≤ z ≤ 100000
  • 0 ≤ s ≤ 15500
  • Poziția inițială a lui Marciuc este 1 1, iar poziția clasei este n n
  • Orice traseu de durată minimă este corect. Dacă băiatul poate merge pe la magazin, în traseu trebuie să apară obligatoriu coordonatele magazinului.
  • Daca numărul minim de secunde este corect dar traseul nu este curect se acordă 40% din punctaj.
  • Pentru teste în valoare de 20 de puncte, s = 0.
  • Pentru teste în valoare de 40 de puncte, n ≤ 100.
  • Marciuc poate trece de mai multe ori prin același loc.
  • O celula surtătură poate fi folosită și ca o celula libera.
  • Fiecare celulă are un singur tip. Nu există scurtături spre celule blocate; celulele 1 1, n n și celula pe care este situat magazinul nu sunt blocate.
  • O scurtatură poate fi traversată prin ambele sensuri.

Exemplu 1

Intrare

5
ENQUEUE Maria
ENQUEUE Andrei
DEQUEUE
ENQUEUE Ioana
ENQUEUE Alexandru

Iesire

['Andrei', 'Ioana', 'Alexandru']

Exemplu 2

Intrare

4
ENQUEUE George
DEQUEUE
DEQUEUE
ENQUEUE Ana

Iesire

Eroare: coada goală ['Ana']

Datele de intrare nu corespund restricțiilor impuse.

Rezolvare

def citeste_date():
    try:
        n = int(input("Introduceți numărul de operațiuni (n): "))
        operatiuni = []
        for _ in range(n):
            operatiune = input().strip()
            operatiuni.append(operatiune)
        return n, operatiuni
    except ValueError:
        return None, None

def valideaza_date(n, operatiuni):
    if not (1 <= n <= 100):
        return False
    for operatiune in operatiuni:
        if not (operatiune.startswith("ENQUEUE ") or operatiune == "DEQUEUE"):
            return False
        if operatiune.startswith("ENQUEUE ") and len(operatiune.split()) != 2:
            return False
        if operatiune.startswith("ENQUEUE ") and not operatiune.split()[1].isalpha():
            return False
    return True

def proceseaza_operatiuni(n, operatiuni):
    coada = []
    for operatiune in operatiuni:
        if operatiune.startswith("ENQUEUE "):
            _, nume = operatiune.split()
            coada.append(nume)
        elif operatiune == "DEQUEUE":
            if coada:
                coada.pop(0)
            else:
                print("Eroare: coada goală")
    return coada

def main():
    n, operatiuni = citeste_date()
    
    if n is None or operatiuni are None or not valideaza_date(n, operatiuni):
        print("Datele de intrare nu corespund restricțiilor impuse.")
        return
    
    print("Datele de intrare corespund restricțiilor impuse.")
    rezultat = proceseaza_operatiuni(n, operatiuni)
    print(rezultat)

if __name__ == "__main__":
    main()