Omówienie zadania Budowa Lotniska (I etap XXXI OI)
Rozwiązanie
W tym podzadaniu mamy zaplanować tylko jeden pas startowy. Ten pas będzie albo zorientowany poziomo, albo pionowo, więc dla tych dwóch orientacji oddzielnie obliczymy wynik i wybierzemy ten większy. Spróbujmy więc znaleźć najdłuższy poziomy pas - dla pionowego można postąpić podobnie. Aby wyznaczyć wynik, dla każdego wiersza wejścia sprawdzamy, jaki jest najdłuższy spójny ciąg składający się z kropek. Najdłuższy pas znajdzie się po lewej stronie pierwszego znaku X w danym wierszu, albo po prawej stronie ostatniego znaku X w wierszu, albo między dwoma kolejnymi znakami X. Jeśli nie ma znaku X to pas zajmuje cały wiersz.
Trzeba jeszcze pamiętać o przypadku brzegowym - jeżeli nie ma żadnej kropki, to wynik wynosi
Rozwiązanie
W rozwiązaniu wzorcowym występują dwa przypadki.
Szukane pasy są równoległe:
Do szukania dwóch równoległych nieprzecinających się pasów startowych możemy ulepszyć rozwiązanie dla
Zamiast szukać najdłuższego pasa, będziemy szukać najdłuższego oraz drugiego najdłuższego pasa. Można utrzymywać oba w kolejnych krokach algorytmu dla
Być może najdłuższy znaleziony pas jest bardzo długi - dłuższy niż dwukrotność długości drugiego najdłuższego pasa. Wtedy opłaca się rozbić najdłuższy pas na dwa. W przeciwnym przypadku wynikiem będzie długość drugiego najdłuższego pasa.
Szukane pasy są prostopadłe,
Jeżeli szukana para najdłuższych pasów jest prostopadła, to na pewno zachodzi jeden z czterech przypadków:
- poziomy pas znajduje się w całości na lewo od pionowego (tzn. jeżeli
to numer kolumny, w której znajduje się pionowy pas, to poziomy pas musi w całości znajdować się w pierwszych kolumnach), - albo poziomy pas znajduje się w całości na prawo od pionowego,
- albo pionowy pas znajduje się w całości nad poziomym,
- albo pionowy pas znajduje się w całości poniżej poziomego.
Wystarczy dla każdego przypadku oddzielnie obliczyć wynik. Można to osiągnąć ładnym trickiem implementacyjnym:
- liczymy wynik przy założeniu, że poziomy pas znajduje się w całości na lewo od pionowego,
- obracamy płaszczyznę o 90 stopni, na przykład korzystając z przekształcenia
dla , - powtarzamy powyższe kroki łącznie cztery razy i wypisujemy największy uzyskany wynik.
Żeby obliczyć wynik przy założeniu, że poziomy pas znajduje się w całości na lewo od pionowego, można przeiterować się po każdej kolumnie, w której miałby być pionowy pas, i postąpić analogicznie do algorytmu dla
Szukane pasy są prostopadłe,
Żeby przyśpieszyć poprzednie rozwiązanie, można obliczyć tablicę
Korzystając z tej tablicy, można w czasie
Gdy rozpatrujemy pionowy pas w
Szukane pasy są prostopadłe,
Zacznijmy od oddzielnego znalezienia najdłuższego poziomego pasa oraz najdłuższego pionowego pasa. Jeżeli się nie przecinają na lotnisku, to poznaliśmy wynik (tzn. długość krótszego z nich). Jeżeli się przecinają, to okazuje się, że wystarczy skrócić te dwa pasy o minimalną liczbę pól tak, aby się już nie przecinały.
Dlaczego nie istnieje lepsza para pasów? Otóż jeżeli optymalne rozwiązanie składa się z dwóch pasów długości