3685 - Primest Prime Pancakes
Cerință[edit | edit source]
Pentru a câștiga niște bani în plus, Ștefan s-a decis să deschidă un magazin nou de clătite pentru următorul sezon estival, deoarece toată lumea e înnebunită dupa clătite vara. Magazinul va vinde n tipuri de clătite, fiecare dintre ele având un cod anume(două clătite pot avea același cod), în funcție de tipul clătitei.
Pentru a afla prețul unei clătite, Ștefan a găsit un algoritm interesant pentru a decide prețul clătitei. Pentru că numerele prime sunt favoritele sale, prețul va depinde de cât de “primă” este clătita.
Astfel:
Prețul inițial al clătitei e x euro, x fiind dat în datele de intrare.
Dacă codul clătitei e un număr prim, prețul crește cu cod + p euro, unde cod e valoarea codului și p e dat în datele de intrare.
Pentru fiecare cifră primă din cod (2, 3, 5, 7), prețul va crește cu d[i] euro, unde valorile d[i] sunt date în datele de intrare.
Dacă suma cifrelor codului este număr prim, prețul crește cu sc euro, unde sc e suma cifrelor codului.
Dacă produsul cifrelor codului este număr prim, prețul crește cu pd euro, unde pd e produsul cifrelor din cod.
Din păcate, această metodă poate să nu ducă la un profit îndeajuns de mare și acum a venit vremea să îl ajutați pe Ștefan să obțină cel mai mare profit posibil. Pentru a realiza acest obiectiv, puteți să schimbați cel mult o cifră din fiecare cod pentru a maximiza suma prețurilor clătitelor.
Totuși, nu puteți face prima cifră egală cu 0 pentru a obține un număr cu o cifră mai puțin, chiar dacă ar putea fi cea mai profitabilă alegere.
Date de intrare[edit | edit source]
Pe prima linie programul va citi numărul n, reprezentând numărul de clătite disponibile în magazinul lui Ștefan.
Pe cea de-a doua linie, programul va citi n numere, reprezentând codurile clătitelor.
Cea de-a treia linie va conține două valori, x și p, cu semnificația din enunț.
Cea de-a patra linie va conține patru valori, d[2] , d[3], d[5], d[7].
Date de ieșire[edit | edit source]
Programul va afișa pe ecran profitul maxim pe care Ștefan îl poate obține după modificarea convenabilă a codurilor clătitelor.
Restricții și precizări[edit | edit source]
- 1 ≤ n ≤ 100 000
- 1 ≤ cod[i] ≤ 999 999
- 1 ≤ x, p, d[i] ≤ 1 000 000
- Pentru teste în valoare de 30 de puncte, 1 ≤ n ≤ 1000.
Exemplul 1:[edit | edit source]
- Intrare
- 4
- 12 89 941 101
- 5 7
- 8 5 3 9
- Ieșire
- Datele de intrare corespund restrictiilor impuse.
- 1907
Exemplul 2:[edit | edit source]
- Intrare
- ha63f
- Ieșire
- Datele de intrare nu corespund restrictiilor impuse.
Rezolvare[edit | edit source]
<syntaxhighlight lang="python" line="1" start="1">
- Functie pentru a verifica daca un numar este prim
def is_prime(pret_n):
if pret_n <= 1: return False if pret_n <= 3: return True if pret_n % 2 == 0 or pret_n % 3 == 0: return False i = 5 while i * i <= pret_n: if pret_n % i == 0 or pret_n % (i + 2) == 0: return False i += 6 return True
- Functie pentru a obtine suma cifrelor unui numar
def sum_digits(pret_n):
return sum(int(digit) for digit in str(pret_n))
- Functie pentru a obtine produsul cifrelor unui numar
def product_digits(pret_n):
product = 1 for digit in str(pret_n): product *= int(digit) return product
- Functie pentru a obtine profitul maxim
def max_profit(pret_n, coduri, pret_x, pret_p, pret_d):
profit = 0 for code in coduri: max_price = pret_n # Parcurgem toate cifrele si incercam sa le schimbam cu o alta cifra for i in range(10): for j in range(len(str(code))): # Cream un nou cod prin schimbarea unei cifre new_code = list(str(code)) new_code[j] = str(i) new_code = int(.join(new_code)) price = pret_x # Verificam daca noul cod este prim si adaugam la pret daca este cazul if is_prime(new_code): price += new_code + pret_p # Adaugam la pret pentru fiecare cifra prima din cod for digit in str(new_code): if is_prime(int(digit)): price += pret_d[int(digit)] # Verificam daca suma cifrelor codului este numar prim si adaugam la pret daca este cazul if is_prime(sum_digits(new_code)): price += sum_digits(new_code) # Verificam daca produsul cifrelor codului este numar prim si adaugam la pret daca este cazul if is_prime(product_digits(new_code)): price += product_digits(new_code) # Actualizam pretul maxim pentru acest cod de clatita max_price = max(max_price, price) # Adaugam la profit pretul maxim obtinut pentru acest cod de clatita profit += max_price return profit
- Functie pentru a verifica daca datele de intrare sunt valide
def verificare_date_intrare(pret_n, coduri, pret_x, pret_p, pret_d):
if 1 <= pret_n <= 100000 and 1 <= pret_x <= 1000000 and 1 <= pret_p <= 1000000 and len(pret_d) == 4: for code in coduri: if 10 <= code <= 999999: continue else: return False return True else: return False
if __name__ == "__main__":
try: print("Introduceți datele de intrare în următoarea ordine, fiecare pe o linie nouă: numărul de coduri, codurile (separate prin spațiu), prețul x și p (separate prin spațiu), prețul d pentru cifrele 2, 3, 5 și 7 (separate prin spațiu).") n = int(input()) codes = list(map(int, input().split())) x, p = map(int, input().split()) d = dict(zip([2, 3, 5, 7], map(int, input().split())))
if verificare_date_intrare(n, codes, x, p, d): # verificam datele de intrare print("Datele de intrare corespund restrictiilor impuse.") print(max_profit(n, codes, x, p, d)) # apelam functia de rezolvare else: print("Datele de intrare nu corespund restrictiilor impuse.") # ne asteptam la 2 tipuri de erori din cauza datelor de intrare, le tratam corespunzator except ValueError: print("Datele de intrare nu corespund restrictiilor impuse.") except IndexError: print("Datele de intrare nu corespund restrictiilor impuse.")
</syntaxhighlight>
Explicație[edit | edit source]
Trebuie să schimbăm prima valoare de la 12 la 17 și vom obține un profit de 45.
Este optim să păstrăm al doilea cod la 89 pentru un profit de 118.
Trebuie să schimbăm cea de-a treia valoare de la 941 la 991 și vom obține un profit de 1022.
Trebuie să schimbăm cea de-a patra valoare de la 101 la 701 și vom obține un profit de 722.
Suma profiturilor va deveni 1907.