1426 - Pozne

De la Universitas MediaWiki

Enunţ

Păcală a împrumutat fiecărei persoane din satul lui un număr de monezi de aur. Unele persoane sunt credule și Păcală, șiret fiind, doar acestora le-a împrumutat un număr de monezi care, scris invers, este număr prim. Mai târziu, când Păcală vrea să își recupereze banii, persoanelor credule le cere cu s monede mai mult decât le-a împrumutat. Unii săteni creduli sunt prieteni cu primarul și numărul care indică suma de bani împrumutată de ei conține cifra c. Aceste persoane știu de vicleșugul lui Păcală și ei, pentru a nu-l denunța la poliție, îi returnează acestuia cu s monede mai puține decât au primit.

Cerinţa

Cunoscându-se numărul n de săteni, cele n valori reprezentând numărul de monede pe care Păcală le-a împrumutat fiecăruia, cifra c și numărul s, se cere să se afișeze: a) numărul de bani împrumutaţi fiecărui sătean care este prieten cu primarul b) numărul persoanelor credule și răspunsul la întrebarea dacă Păcală a câștigat monezi în plus față de cele împrumutate: dacă da, se va afișa pe ecran valoarea 1; dacă nu se va câștiga nimic în plus și nici nu va pierde nimic se va afișa valoarea 0, iar dacă va pierde monezi față de cele împrumutate se va afișa valoarea -1.

Date de intrare

Fișierul de intrare pozne.in conține pe prima linie numărul p. Dacă p este egal cu 1, în fișierul pozne.out se va afișa doar cerința de la punctul a), iar dacă p este egal cu 2, în fișierul pozne.out se va afișa doar cerința de la punctul b).

A doua linie conține numerele n s c, în această ordine, iar a treia linie conține n valori, reprezentând numărul de monezi împrumutate de Păcală sătenilor

Date de ieșire

Dacă datele sunt introduse corect, în fișier se va afișa: "Datele sunt introduse corect.", apoi pe urmatorul rand fișierul de ieșire pozne.out conţine o singură linie pe care se va afișa: - pentru cerința a), un şir de numere, separate prin spații, fiecare număr reprezentând numărul de monezi împrumutate unui sătean care este prieten cu primarul (în ordinea în care apar aceste numere în fişierul de intrare). - pentru cerința b), două numere cu spațiu între ele cu semnificația din enunț.În cazul în care datele nu respectă restricțiile, se va afișa pe ecran: "Datele nu corespund restricțiilor impuse.".

Restricții și precizări

  • 0 < n ⩽ 1000; 0 < s ⩽ 500000; 0 ⩽ c ⩽ 9
  • 0 < numărul monezilor împrumutate de fiecare sătean ⩽ 999999
  • 0 ⩽ numar1 ⩽ numar2 ⩽ 1.000.000.000
  • Se garantează că in șir există cel puțin un număr care, scris invers, este număr prim.

Exemplul 1

pozne.in
1
7 15 3
121 31 50 33 821 23 91
pozne.out
Datele sunt introduse corect.
31 33 23

Explicație

Cerința este 1. În ogradă sunt 2 găini și 3 văcuțe.

Exemplu2

pozne.in
2
7 15 3
121 31 50 33 821 23 91
pozne.out
Datele sunt introduse corect.
3 1

Explicație

Se afișează 3 deoarece 31, 50 și 91, scrise invers, sunt numere prime:

31 -> 13 50 -> 5 91 -> 19 și 1 deoarece din cele 3 numere doar de la unu Păcală pierde monezi și de la celelalte 2 persoane câștigă monezi. Deci, prin vicleșug, Păcală câștigă mai mulți bani decât pierde:

31 conține cifra c ( -s=-15) 50 nu conține cifra c (+s=+15) 91 nu conține cifra c (+s=+15)

Rezolvare

def validare_date(n, s, c):
    if n <= 0 or n > 1000:
        return False
    if s <= 0 or s > 500000:
        return False
    if c < 0 or c > 9:
        return False
    return True


def prim(n):
    cnt = 0
    for i in range(1, int(n ** 0.5) + 1):
        if n % i == 0:
            cnt += 2
        if i * i == n:
            cnt -= 1
    if cnt == 2:
        return 1
    else:
        return 0


def contine(n, c):
    contine = False
    while n:
        if n % 10 == c:
            contine = True
        n //= 10
    if contine:
        return 1
    else:
        return 0


if __name__ == '__main__':
    with open("pozne.in", "r") as f_in:
        p = int(f_in.readline())
        n, s, c = map(int, f_in.readline().split())
        monede = list(map(int, f_in.readline().split()))

    with open("pozne.out", "w") as f_out:
        if not validare_date(n, s, c):
            f_out.write("Datele nu corespund restricțiilor impuse.")
        else:
            f_out.write("Datele sunt introduse corect.\n")

    if p == 2:
        cnt = 0
        sum = 0
        for x in monede:
            ogl = int(str(x)[::-1])
            if prim(ogl):
                cnt += 1
                if contine(x, c):
                    sum -= s
                else:
                    sum += s

        with open("pozne.out", "a") as f_out:
            if sum > 0:
                f_out.write(str(cnt) + " 1")
            elif sum == 0:
                f_out.write(str(cnt) + " 0")
            else:
                f_out.write(str(cnt) + " -1")

    elif p == 1:
        with open("pozne.out", "a") as f_out:
            for x in monede:
                if contine(x, c):
                    f_out.write(str(x) + " ")

Explicație rezolvare

Funcția validare_date(n, s, c): verifică dacă valorile citite din fișierul de intrare respectă restricțiile problemei.Astfel returnează True dacă datele respectă restricțiile, altfel returnează False.
Funcția prim(n) determină dacă un număr este prim sau nu.
Funcția contine(n, c) verifică dacă numărul întreg n conține cifra c. Se parcurg cifrele numărului n prin împărțiri succesive la 10 și se verifică dacă restul împărțirii acestuia la 10 este egal cu c. Funcția returnează 1 dacă numărul conține cifra c, altfel returnează 0.
În funcția main, se deschide fișierul de intrare "pozne.in" și se citesc valorile p, n, s, c și lista de n numere întregi numită monede. Se verifică dacă datele citite respectă restricțiile cu ajutorul funcției validare_date(n, s, c). Dacă datele nu respectă restricțiile, se afișează un mesaj în fișierul de ieșire "pozne.out", altfel se afișează mesajul "Datele sunt introduse corect.".
Dacă p este egal cu 2, atunci pentru fiecare element x din listă, se determină numărul întreg oglindit al lui x (prin inversarea cifrelor). Acest număr oglindit se verifică dacă este prim sau nu prin apelarea funcției prim. Dacă numărul oglindit este prim, se mărește un contor cnt și se adaugă valoarea lui s la variabila sum dacă x nu conține cifra c, sau se scade valoarea lui s din sum dacă x conține cifra c.
La sfârșitul buclei, se scrie în fișierul de ieșire pozne.out o anumită valoare, în funcție de valoarea lui sum. Dacă sum este mai mare decât zero, se scrie valoarea lui cnt urmată de 1. Dacă sum este zero, se scrie valoarea lui cnt urmată de 0. Dacă sum este mai mic decât zero, se scrie valoarea lui cnt urmată de -1.
Dacă p este egal cu 1, atunci pentru fiecare element x din listă, se verifică dacă acesta conține cifra c prin apelarea funcției contine. Dacă x conține cifra c, se scrie valoarea lui x în fișierul de ieșire pozne.out