3685 - Primest Prime Pancakes

De la Universitas MediaWiki

Cerință

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

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

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

  • 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:

Intrare
4
12 89 941 101
5 7
8 5 3 9
Ieșire
Datele de intrare corespund restrictiilor impuse.
1907

Exemplul 2:

Intrare
ha63f
Ieșire
Datele de intrare nu corespund restrictiilor impuse.

Rezolvare

# 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.")

Explicație

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.