Przeskocz do treści

Delta mi!

Informatyczny kącik olimpijski

Wybrakowany ciąg

Tomasz Idziaszek

o artykule ...

  • Publikacja w Delcie: listopad 2014
  • Publikacja elektroniczna: 31-10-2014

W tym miesiącu omówimy zadanie Sequence, które pojawiło się na tegorocznej edycji Bałtyckiej Olimpiady Informatycznej.

obrazek

Zadanie. Na tablicy napisano math kolejnych liczb całkowitych math Następnie z każdej liczby usunięto wszystkie cyfry oprócz jednej. Znając ciąg math cyfr math które pozostały na tablicy, należy wyznaczyć minimalną wartość math od której mógł zaczynać się pierwotny ciąg.

Przykładowo, ciąg cyfr math mógł powstać z pięciu kolejnych liczb naturalnych w następujący sposób: math

Zacznijmy od prostej obserwacji, że dla każdego ciągu cyfr szukana liczba math istnieje. Wystarczy zauważyć, że dla math wszystkie liczby z ciągu math zaczynają się od prefiksu zawierającego wszystkie możliwe cyfry.

Zadanie jest niełatwe i tylko jeden z uczestników olimpiady zdobył za nie maksymalną liczbę punktów. Kluczowe dla rozwiązania jest przyjrzenie się cyfrze jedności liczby math; oznaczmy ją przez math Wyznacza ona jednoznacznie cyfry jedności pozostałych liczb pierwotnego ciągu - będą to kolejno

display-math

Jeśli math to pozostałe cyfry math-tej liczby mogą być dowolne. W przeciwnym przypadku cyfra math musi się pojawić na dalszej pozycji w math-tej liczbie. Podzielmy teraz poszukiwany ciąg na bloki zaczynające się na takich pozycjach, że math lub math Każdy blok (oprócz pierwszego i ostatniego, które mogą być krótsze) zawiera 10 liczb, które w pierwotnym ciągu będą się różnić jedynie na cyfrze jedności. Zatem ich wspólny prefiks będzie musiał zawierać wszystkie cyfry ze zbioru math gdzie math jest początkową pozycją bloku. Możemy więc rozważyć 10 razy krótszy ciąg - jego elementy będą zbiorami cyfr, które muszą wystąpić w kolejnych blokach, i powtórzyć powyższe rozumowanie.

Zatem zadanie rozwiązujemy rekurencyjnie: dla danego math-elementowego ciągu math zawierającego zbiory cyfr, które mają wystąpić w kolejnych liczbach, należy wyznaczyć minimalne math Jeśli math to odpowiedzią jest liczba zawierająca wszystkie cyfry ze zbioru math (w kolejności rosnącej). Dla math mamy dwa przypadki: albo math i wtedy liczby mają ten sam prefiks, więc rekurencyjnie znajdujemy rozwiązanie dla zbioru cyfr math albo math i rekurencyjnie rozpatrujemy ciąg math wiedząc, że nie opłaca nam się więcej rozpatrywać drugiego przypadku. Zatem rozwiązanie dla ciągów długości math znajdujemy w czasie stałym.

W końcu dla math przeglądamy wszystkich 10 kandydatów math na cyfrę jedności math Dla każdego z nich budujemy ciąg o długości math zawierający sumy zbiorów dla kolejnych bloków, i rekurencyjnie wyznaczamy dla niego wartość math Szukane math to minimum ze zbioru math

Złożoność czasowa algorytmu wyraża się wzorem rekurencyjnym

display-math

którego rozwiązaniem jest math

Niestety, powyższy algorytm ma dość istotny feler - działa przy założeniu, że liczby w pierwotnym ciągu mogą mieć zera wiodące (np. dla math i zbioru math konstruujemy math zamiast poprawnego math). I, jak to zwykle bywa w zadaniach tego typu, naprawienie tej usterki wymaga dość żmudnego przyjrzenia się poszczególnym przypadkom, w którym takie zero może się pojawić. W szczególności, gdy cyfra jedności jednej z liczb należącej do bloku jest "istotnym" zerem (czyli math oraz math ), wygodnie jest dorzucić do zbioru math odpowiadającego temu blokowi dodatkowy element sygnalizujący, że w math musi wystąpić jakaś niezerowa cyfra. Szczegóły techniczne pozostawimy do dopracowania Czytelnikom.