2935 - Robot 5

De la Universitas MediaWiki

Sursă: [1]

Cerință

Pe un cerc se află N poziții, consecutiv așezate și notate cu 1,2,3,...,N. Distanțele între oricare două poziții vecine sunt egale cu un pas. Un robot se află inițial la poziția 1. În una dintre poziții se află un depozit cu cantitatea X de energie, de la care robotul se poate alimenta. Robotul se poate deplasa pe cerc numai în sensul acelor de ceas. Robotul poate păstra o cantitate maximă W de energie, iar inițial este alimentat la capacitate maximă. Pentru fiecare pas robotul cheltuiește o unitate de energie. 1) Precizându-se numărul de poziții N, energia inițială a robotului W, poziția P a depozitului și cantitatea X de energie existentă inițial în depozit, se cere să se precizeze numărul de pași pe care îi poate efectua robotul. 2) Precizându-se numărul de poziții N, energia inițială a robotului W și cantitatea X de energie existentă inițial în depozit, se vor determina și afișa numărul maxim de pași pe care îi poate efectua robotul și cea mai mică poziție, convenabil aleasă, unde se poate instala depozitul pentru obținerea numărului maxim de pași.

Date de intrare

Pe primul rând al fișierului text robot5.in se află numărul natural C reprezentând cerința. Dacă C=1, atunci pe al doilea rând și separate prin câte un spațiu se vor afla scrise numerele naturale N, W, X și P. Dacă C=2, atunci pe al doilea rând și separate prin câte un spațiu se vor afla scrise numerele naturale N, W și X.

Date de ieșire

Dacă datele sunt introduse corect, pe ecran se va afișa: "Datele sunt corecte.". Dacă C=1, atunci în fișierul de ieșire robot5.out se va scrie un număr natural reprezentând numărul de pași pe care îi poate efectua robotul, iar dacă C=2, atunci în fișierul text robot5.out se vor scrie două numere naturale separate prin spațiu reprezentând numărul maxim de pași pe care îi poate efectua robotul și cea mai mică poziție a depozitului, convenabil aleasă pentru obținerea numărului maxim de pași. În caz contrar, se va afișa pe ecran: "Datele nu sunt comform restricțiilor impuse.".

Restricții și precizări

  • Când ajunge la depozit robotul se alimentează cu maximul de energie posibil, iar cantitatea de energie din depozit scade corespunzător.
  • 2 ≤ N ≤ 10.000
  • 1 ≤ W ≤ 1.000.000.000
  • 1 ≤ X ≤ 1.000.000.000
  • 1 ≤ P ≤ N

Exemple

Exemplu 1

robot5.in
1
6 3 3 3
robot5.out
5

Explicatie

Avem cerința 1, câți pași va putea face robotul. El are inițial 3 unități de energie și se află la poziția 1 și deci va putea ajunge la poziția 3 din 2 pași folosind 2 unități de energie. Când ajunge la poziția 3 mai are 1 unitate de energie și se alimentează din depozit cu 2 unități, refăcând cele 3 unități de energie maxim posibile. Mai poate face 3 pași și astfel ajunge la poziția 6 cu 0 unități de energie și se oprește. În total a efectuat 5 pași.

Exemplu 2

robot5.in
2
6 3 3
robot5.out
6 4

Explicatie

Depozitul se va instala la poziția 4 și robotul va putea efectua 6 pași, care este maxim.

Rezolvare

import sys
def citeste_n():
    while True:
        try:
            with open("robot5.in") as fin:
                c = int(fin.readline().strip())
                if c >= 1 and c <= 2:
                    print("Datele sunt corecte.")
                    return c
                else:
                    print("Datele nu sunt conform restrictiilor impuse.")
        except ValueError:
            print("Trebuie introduse doar numere intregi.")


def citeste_perechi(c):
    valori = []
    with open("robot5.in") as fin:
        next(fin)
        for i in range(1):
            try:
                line = fin.readline().strip()
                if not line:
                    raise ValueError("Linia este goala.")
                if c == 1:
                    N, W, X, P = map(int, line.split())
                    if 2 <= N <= 100000 and 1 <= W <= 1000000000 and 1 <= X <= 1000000000 and 1 <= P <= N:
                        print("Datele sunt corecte.")
                        valori.append((N, W, X, P))
                    else:
                        print("Datele nu sunt conform restrictiilor impuse.")
                else:
                    N, W, X = map(int, line.split())
                    if 2 <= N <= 100000 and 1 <= W <= 1000000000 and 1 <= X <= 1000000000:
                        print("Datele sunt corecte.")
                        valori.append((N, W, X))
                    else:
                        print("Datele nu sunt conform restrictiilor impuse.")
            except ValueError as e:
                print(f"Linia {i+2}: {e}")
                valori.append(None)

    return [v for v in valori if v is not None]

def robot5(valori):
    rezultate = []
    for valoare in valori:
        N, W, X = valoare[:3]
        if len(valoare) == 4:
            P = valoare[3]
            distanta = min(N - P + 1, P) - 1
            pasi = min(distanta, W // X)
        else:
            pasi = W // X

        rezultate.append(pasi)

    with open("robot5.out", "w") as fout:
        for rezultat in rezultate:
            fout.write(str(rezultat) + "\n")
            if len(valoare) == 3:
                pozitie = -1
                max_pasi = 0
                for i in range(1, N + 1):
                    distanta = min(N - i + 1, i) - 1
                    pasi = min(distanta, W // X)
                    if pasi > max_pasi:
                        max_pasi = pasi
                        pozitie = i
                fout.write(str(max_pasi) + " " + str(pozitie) + "\n")

if _name_ == '_main_':
    n = citeste_n()
    valori = citeste_perechi(n)
    robot5(valori)

Explicatie

Acest cod are ca scop citirea datelor dintr-un fișier de intrare și apoi procesarea acestora pentru a obține un rezultat, care este scris într-un fișier de ieșire.
Funcția citeste_n() deschide fișierul "robot5.in" și citește prima linie, care ar trebui să conțină un număr întreg c. Aceasta verifică dacă c este în intervalul [1, 2]. Dacă este, funcția returnează valoarea c, în caz contrar afișează un mesaj de eroare și cere introducerea unui alt număr.
Funcția citeste_perechi(c) deschide fișierul "robot5.in" și citește linia a doua, apoi procesează fiecare linie pentru a verifica dacă datele sunt conforme cu cerințele problemei. Aceasta verifică dacă valorile citite sunt întregi și se încadrează în intervalele specificate. Dacă valorile sunt conforme, ele sunt adăugate la lista de valori de returnat, altfel este afișat un mesaj de eroare.
Funcția robot5(valori) primește lista de valori prelucrate și apoi calculează pentru fiecare valoare numărul de pași pe care îi poate face robotul, având în vedere restricțiile din enunțul problemei. Aceasta adaugă rezultatul obținut într-o listă de rezultate.
În cele din urmă, funcția robot5(valori) scrie fiecare rezultat într-un fișier de ieșire "robot5.out". Pentru datele care nu conțin parametrul P, se calculează distanța maximă și poziția corespunzătoare acesteia, care sunt scrise și în fișierul de ieșire.