0722 - Cifru

From Bitnami MediaWiki

Alibaba trebuie să descopere cifrul care deschide cufărul cu comoara cea mare. Cifrul este foarte greu de găsit. El a descoperit mai multe pietre, fiecare piatră având o altă culoare, pe fiecare piatră fiind scris un număr natural cu cel mult 4 cifre. Alibaba observă că numerele de pe fiecare piatră sunt distincte două câte două. Regula după care se formează cifrul este una foarte simplă, şi Alibaba a reuşit să o obţină destul de uşor: cifrul este format din alăturarea într-o anumită ordine a tuturor pietrelor. Ceea ce Alibaba mai ştie este că pe poziţia p din cifru se găseşte cu siguranţă cifra k.

Cerința[edit | edit source]

Scrieţi un program care determină numărul de variante de cifruri pe care va trebui să le încerce Alibaba. Numărul fiind foarte mare se va calcula modulo 46337.

Date de intrare[edit | edit source]

Fișierul de ieșire cifru.out va conține pe prima linie trei numere naturale n, p şi k separate printr-un spaţiu, reprezentând numărul total de numere de pe pergament, poziţia p şi respectiv cifra k care se găseşte pe poziţia p în cifru. Pe următoarele n linii se găseşte câte unul din cele n numere de pe pergament.

Date de ieșire[edit | edit source]

Pe prima linie a fişierului de ieşire cifru.out se va scrie un număr natural reprezentând numărul de variante modulo 46337 de cifruri pe care va trebui să le încerce Alibaba.

Restricții și precizări[edit | edit source]

  • 0 < n < 25
  • Numerele de pe fiecare piatră sunt strict pozitive mai mici decât 10000 şi sunt distincte două câte două.
  • 0 ≤ k ≤ 9
  • Două cifruri diferă între ele prin ordinea de aşezare a pietrelor, chiar dacă numărul obţinut prin citirea numerelor de pe pietre este aceeaşi. De exemplu dacă există trei pietre având inscripţionate numerele 12, 3 şi respectiv 123, ele se pot lipi astfel: 12-3-123, 123-12-3, cele două cifruri considerându-se diferite, cifrele având culori diferite.

Rezolvare[edit | edit source]

<syntaxhighlight lang="python3"> MOD = 46337

def count_cipher_variants(n, p, k, numbers):

   """Calculates the number of cipher variants modulo MOD."""
  
   total_variants = 1  # One variant with all numbers fixed except for the given one
   fixed_numbers = set([k])  # Set of fixed numbers (initially only k)
   remaining_numbers = set(numbers) - fixed_numbers  # Set of remaining numbers
   for i in range(p - 1, -1, -1):
       choices_for_position_i = len(remaining_numbers)
       total_variants *= choices_for_position_i


       fixed_numbers.add(numbers.pop(i))  # Add the number to fixed numbers
       remaining_numbers.remove(numbers.pop(i))  # Remove it from remaining numbers
   return total_variants % MOD

def main():

   n, p, k = map(int, input().split())
   numbers = [int(input()) for _ in range(n)]
   cipher_variants = count_cipher_variants(n, p, k, numbers)
   print(cipher_variants)

if __name__ == "__main__":

   main()

</syntaxhighlight>