3720 - Aproape

De la Universitas MediaWiki

Sursa: [1]


Cerinţa

Cunoscând numărul N, să se scrie un program care determină: 1. Numărul de cifre ale acestui număr. 2. Numărul de numere aproape de N. 3. Numărul de numere aproape de cel puțin un număr aproape de N.

Date de intrare

Fișierul de intrare aproape.in conține pe prima linie un număr V a cărui valoare poate fi doar 1, 2 sau 3, iar pe a doua linie numărul natural N.

Date de ieșire

Dacă datele sunt introduse corect, pe ecran se va afișa: "Datele sunt introduse corect.", apoi: * Dacă valoarea lui V este 1, atunci fișierul aproape.out va conține pe prima linie un singur număr ce reprezintă numărul de cifre ale lui N.

  • Dacă valoarea lui V este 2, atunci fișierul aproape.out va conține pe prima linie un singur număr natural ce reprezintă numărul de numere aproape de N.
  • Dacă valoarea lui V este 3, atunci fișierul aproape.out va conține pe prima linie un singur număr natural ce reprezintă numărul de numere aproape de un număr aproape de N.

În caz contrar, pe ecran se va afișa: "Datele nu au fost introduse corect."

Restricţii şi precizări

  • 0 ≤ N < 1.000.000.000
  • Pentru teste în valoare de 20 de puncte avem V = 1.
  • Pentru teste în valoare de 30 de puncte avem V = 2.
  • Pentru teste în valoare de 50 de puncte avem V = 3.
  • Aveți grijă să nu numărați vreun număr de mai multe ori!

Exemple

Exemplul 1

aproape.in
1
1903
Ecran
Datele sunt introduse corect.
aproape.out
4

Exemplul 2

aproape.in
2
1903
Ecran
Datele sunt introduse corect.
concurs.out
5

Exemplul 3

aproape.in
3
1903
Ecran
Datele sunt introduse corect.
aproape.out
15

Rezolvare

# 3720

def verifica_restricții(v, n):
    if v not in (1, 2, 3):
        return False
    if not 0 <= n < 1000000000:
        return False
    return True


def numar_cifre(n):
    return len(str(n))


def este_aproape(n, m):
    if numar_cifre(n) != numar_cifre(m):
        return False
    diferenta = 0
    while n > 0:
        if n % 10 != m % 10:
            diferenta += 1
        if diferenta > 1:
            return False
        n //= 10
        m //= 10
    return diferenta == 1


def numara_aproape(n):
    cnt = 0
    for i in range(1, 10):
        m = n - (n % 10) + i
        if m != n and este_aproape(n, m):
            cnt += 1
        m = n - (n % 10) - i
        if m != n and este_aproape(n, m):
            cnt += 1
    return cnt


def rezolva_problema(v, n):
    if v == 1:
        return numar_cifre(n)
    elif v == 2:
        return numara_aproape(n)
    elif v == 3:
        cnt_aproape = numara_aproape(n)
        cnt_total = cnt_aproape
        for i in range(1, 10):
            m = n - (n % 10) + i
            if m != n:
                cnt_total += numara_aproape(m)
            m = n - (n % 10) - i
            if m != n:
                cnt_total += numara_aproape(m)
        return cnt_total


if __name__ == '__main__':
    with open('aproape.in', 'r') as fin:
        v = int(fin.readline().strip())
        n = int(fin.readline().strip())
    if verifica_restricții(v, n):
        print('Datele sunt introduse corect.')
        rezultat = rezolva_problema(v, n)
        with open('aproape.out', 'w') as fout:
            fout.write(str(rezultat) + '\n')
    else:
        print('Datele nu au fost introduse corect.')

Explicație rezolvare

Funcția verifica_restricții(v, n) verifică dacă valorile din fișier sunt valide. v poate fi doar 1, 2 sau 3, iar n trebuie să fie un număr între 0 și 999999999. Dacă valorile nu sunt valide, funcția returnează False, altfel returnează True.

Funcția numar_cifre(n) primește un număr n și returnează numărul de cifre din acesta.

Funcția este_aproape(n, m) primește două numere n și m și returnează True dacă cele două numere sunt diferite doar într-o singură cifră.

Funcția numara_aproape(n)primește un număr n și calculează câte numere sunt aproape de n, adică diferă de n doar într-o singură cifră.

Funcția rezolva_problema(v, n) primește un număr v și un număr n și returnează un rezultat bazat pe valorile de input. Dacă v este 1, atunci funcția returnează numărul de cifre din n. Dacă v este 2, funcția returnează numărul de numere apropiate de n. Dacă v este 3, funcția calculează numărul total de numere apropiate de n și toate numerele apropiate de n cu o singură cifră diferită.

În blocul if __name__ == '__main__':, programul începe prin citirea valorilor de input din fișierul "aproape.in". Dacă valorile de input sunt valide, atunci se calculează rezultatul și se scrie în fișierul "aproape.out". Dacă valorile de input nu sunt valide, atunci se afișează un mesaj de eroare.