• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Optymalne uzupełnianie tablicy

Object Storage Arubacloud
+1 głos
377 wizyt
pytanie zadane 15 grudnia 2017 w C i C++ przez NiCKo Początkujący (490 p.)
Cześć! Mam pewien problem i nie wiem, jak go rozwiązać. Jest tu coś na kształt Tetrisa. Mam tablicę dwuwymiarową i w tej tablicy jest tak (na przykład 20 wierszy po 10 kolumn):

................
................
................
##......##..#
#########

Dodatkowo mam sprecyzowane następujące po sobie figury typowo tetrisowe, które mogę obracać i moim zadaniem jest je optymalnie rozmieścić w tych lukach, aby jak najwięcej usunąć linii (jak w Tetrisie).
Nie wiem, jak rozpracować to optymalne rozmieszczenie figur, jak się odwołać, że akurat tu ma być ta figura, a jeżeli jest możliwość jej rozmieszczenia na kilka sposobów, to żeby program sprawdził, które rozmieszczenie jest najkorzystniejsze (rekurencja?). Później dla kolejnej figury trzeba zrobić to samo i dla kolejnej - czyli sprawdzić, który scenariusz rozmieszczenia figur będzie najoptymalniejszy.
Ktoś mógłby mi dać jakąś wskazówkę? Na razie myślałam nad grafami, że mogłoby to być to, zazwyczaj grafy wykorzystuje się do wyznaczania najkrótszej drogi i ma to pewien sens, ale nie wiem, jak to dalej pociągnąć.
Dzięki z góry za rady!
komentarz 15 grudnia 2017 przez adrian17 Ekspert (344,860 p.)
Zanim coś więcej powiem - skąd wziąłeś to zadanie?
komentarz 15 grudnia 2017 przez NiCKo Początkujący (490 p.)
Z konkursu programistycznego.
komentarz 15 grudnia 2017 przez adrian17 Ekspert (344,860 p.)

Bo matematycznie udowodniono (link, ale nie próbuj tego czytać), że maksymalizacja usuniętych linii w tetrisie to problem NP-kompletny - czyli, w uproszczeniu, nie ma algorytmu znajdującego optymalne rozwiązanie w rozsądnym czasie.

W konkursie chodziło o znalezienie idealnego rozwiązania, czy "w miarę dobrego, im lepszego tym więcej punktów"? Jeśli to pierwsze, to (o ile nie zauważyłem jakiegoś szczegółu upraszczającego to zadanie) dość dziwny dobór zadań ;)

W każdym razie...

Jakoś nie widzę opcji z grafem, bo błyskawicznie napęcznieje; ja bym zaczął ogólnie od jakiegoś naiwnego rozwiązania jako punkt wyjściowy i zastanawiał się dalej mając już coś działającego.

komentarz 15 grudnia 2017 przez NiCKo Początkujący (490 p.)
Dokładnie tu chodzi o to, ile maksymalnie można usunąć linii przy optymalnym rozkładzie nadchodzących klocków w sytuacji podanej na wejściu i to mam podać na wyjściu - ilość linii.
Mam przytoczyć całe zadanie? Generalnie, dla podanego przykładu udało mi się faktycznie, wyznaczyć optymalne rozwiązanie, ale to na kartce - w tym rzecz, że nie wiem, jak to "zautomatyzować".

O czym mniej więcej myślisz pisząc o naiwnym rozwiązaniu?
komentarz 15 grudnia 2017 przez adrian17 Ekspert (344,860 p.)
"naiwny" zazwyczaj oznacza "wariant prostszy i łatwiejszy do zaimplementowania, ale niekoniecznie optymalny".

Jeśli liczba klocków jest mała, to może faktycznie da się brute-force'm sprawdzić wszystkie opcje (tylko wycinając te kompletnie bez sensu).

1 odpowiedź

+1 głos
odpowiedź 16 grudnia 2017 przez mokrowski Mędrzec (155,460 p.)
edycja 16 grudnia 2017 przez mokrowski

Ja bym wyszedł od rozwiązania siłowego a później się zastanawiał...

Zacznij od maksymalizacji wypełnienia ostatniej linii, biorąc sekwencje które są permutacjami zbioru klocków.

A nieco prościej:

  1. Wyzeruj ilość maksymalną linii.
  2. Weź permutację klocków Tetris.
  3. Weź pierwszy klocek wybranej permutacji.
  4. Ułóż klocek tak aby zmaksymalizować wypełnienie ostatniej linii.
  5. Usuń klocek z wygenerowanej permutacji
  6. Jeśli są klocki, wróć do 3.
  7. Zapisz ilość osiągniętych linii jeśli większa od bieżącej maksymalnej.
  8. Jeśli jest następna permutacja wróć do 2.
  9. Wypisz wynik.
komentarz 16 grudnia 2017 przez NiCKo Początkujący (490 p.)
1) Nie mogę wziąć permutacji nadchodzących klocków, bo mam je układać właśnie w zadanej kolejności - jest ona narzucona i basta.
2)  "4, Ułóż klocek tak aby zmaksymalizować wypełnienie ostatniej linii." - W jaki sposób? Jak to zautomatyzować? Jak mam wskazać, że skoro tu, tam i jeszcze gdzieś indziej jest miejsce, to ma wybrać jedno z tych kilku. A może ma sprawdzić wszystkie? No, ale właśnie - jak?
komentarz 16 grudnia 2017 przez mokrowski Mędrzec (155,460 p.)
Ad 1. Ok. Tu nie masz wyjścia.

Ad 2. No to będziesz na początku siłowo przeglądał wszystkie kombinacje zrzucenia obróconego klocka. Oczywiście obroty także będą wszystkie. Czyli 2 pętle i notowanie wyniku w postaci skompletowanych linii. Jak? No po prostu napisać :-)

Jak więc zrozumiałem do siłowego rozwiązania pozostaje przejrzenie tych kombinacji. Jak to zrobisz, zauważysz że np. rozwiązanie w postaci budowania "drapacza chmur" czyli każdy klocek na innym, nie prowadzi do maksymalizacji wypełnionych linii. Dodasz warunek usunięcia takich kombinacji. Analogicznie dla kliku "nie stykających się drapaczy chmur".

Mi sprawdza się strategia: jak nie wiem jak zacząć, zaczynam od rozwiązania siłowego choćby po to by wiedzieć gdzie jest poziom rozwiązania najmniej optymalnego.

Tu napiszesz funkcje które i tak Ci się przydadzą (np. obrót klocka i detekcja minimalnej współrzędnej na której może leżeć).

Podobne pytania

0 głosów
0 odpowiedzi 156 wizyt
pytanie zadane 1 stycznia 2018 w Python przez Ciartek Nowicjusz (210 p.)
0 głosów
2 odpowiedzi 24,173 wizyt
pytanie zadane 3 września 2015 w Offtop przez k222 Nałogowiec (30,150 p.)
0 głosów
0 odpowiedzi 329 wizyt
pytanie zadane 24 września 2019 w C i C++ przez jjanickij Użytkownik (510 p.)

92,555 zapytań

141,403 odpowiedzi

319,560 komentarzy

61,940 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...