https://pl.spoj.com/problems/AL_11_05
https://spoj.com/ALGOLIGA/problems/AL_11_05
Skrócony opis problemu:
Dana jest plansza o rozmiarze n w kształcie piramidy złożonego z kwadratowych pól. Następnie danych jest t mniejszych lub równych piramid będących częścią planszy. Należy obliczyć obszar planszy pokryty owymi piramidami (czyli podać ilość kwadratów, które zostały przykryte t piramidami). Oto przykładowa plansza z 2 naniesionymi piramidami (wynik to 8, bo mamy 8 zamalowanych kwadratów):
Rozwiązanie naiwne:
Możemy oczywiście utworzyć sobie tablicę dwuwymiarową reprezentującą planszę (na początku pustą) i dla każdej z t piramid zamalowywać odpowiednie pola planszy, a na końcu je zliczyć.
Złożoność: O(n^2 \cdot t), bo pesymistycznie każda piramida do zamalowania może mieć rozmiar bliski n, a piramida o rozmiarze n składa się z \frac{n \cdot (n+1)}{2} kwadratów. Na końcu przejście całej planszy również zajmie nam \frac{n \cdot (n+1)}{2} operacji.
Rozwiązanie sprytne:
Bardziej ambitnym czytelnikom polecam nieczytanie poniższego rozwiązania, a spróbowanie najpierw dojście do niego samemu po sprawdzeniu jego złożoności, która została podana poniżej. Wydaje mi się, że złożoność sporo podpowie.
A zatem, na pewno nie możemy dla każdej piramidy zaznaczać w jej wszystkich kwadratów na planszy. Nie powinniśmy również wykonywać nawet O(n) operacji dla pojedynczej piramidy, gdyż wtedy złożoność wyniosłaby O(n^2 + t \cdot n), a i to jest za wolne przy ograniczeniach z zadania. Dla każdej piramidy musimy wykonać zatem albo stałą, albo logarytmiczną ilość operacji. Możemy też wywnioskować z ograniczeń z zadania, że po przetworzeniu wszystkich macierzy możemy nawet przejść całą planszę, kwadrat po kwadracie (bo n=5000, a kilkadziesiąt milionów operacji nie jest problemem).
Na początku myślałem, że trzeba dla każdego wiersza tworzyć jakieś drzewo, ale okazuje się, że nie! Możemy utworzyć pustą planszę i dla każdej piramidy po prostu zaznaczać w danej komórce rozmiar piramidy, która się w niej zaczyna. Czyli dla piramidy z przykładu, której rysunek znajduje się powyżej w komórce a_{2, 1} znajdzie się liczba 2, a w komórce a_{2, 2} znajdzie się liczba 3.
Przy zliczaniu, kiedy dojdziemy do jakiejś zajętej komórki, po prostu dodamy do wyniku 1 licząc jedynie szczyt piramidy, a następnie dodamy 2 piramidy, o 1 rozmiar mniejsze. Tak więc dla a_{2, 1} wpiszemy w komórki a_{3, 1} i a_{3, 2} wartość 2-1=1, a w komórki a_{3, 2} i a_{3, 3} liczbę 3-1=2. Czyli dzielimy piramidę na: szczyt (złożony z 1 kwadratu), lewą podpiramidę o rozmiarze o 1 mniejszym i prawą podpiramidę o rozmiarze o 1 mniejszym. Jak widzimy, 2 razy zaktualizowaliśmy komórkę a_{3, 2}. Musimy pamiętać, że możemy aktualizować komórkę TYLKO na wartość większą. Dotyczy to również wczytywania. Czyli jeśli mamy w jakiejś komórce wartość 5, to możemy ją zmienić na 7, ale odwrotnie już nie (bo interesuje nas maksymalny obszar pokryty przez piramidy).
Złożoność: O(t + n^2), bo dla każdej piramidy wykonujemy stałą ilość operacji, a na końcu przechodzimy planszę, która ma \frac{n \cdot (n+1)}{2} pól.
Optymalizacja:
Jeśli rozmiar jakiejś piramidy będzie wynosił n, to wiemy już, że jest to maksymalna piramida pokrywająca całą planszę. Możemy wtedy wypisać \frac{n \cdot (n+1)}{2} i zakończyć program.
Optymalizacja:
Jeśli rozmiar jakiejś piramidy będzie wynosił n, to wiemy już, że jest to maksymalna piramida pokrywająca całą planszę. Możemy wtedy wypisać \frac{n \cdot (n+1)}{2} i zakończyć program.
Know your sodium limit
OdpowiedzUsuń• Healthy adults need to limit their sodium intake to no more than 2,300 mg per day
(about 1 teaspoon of salt)
http://booksg.com/index.php/acca-books/115-low-salt-cook-book-know-your-sodium-limit