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

Optymalizacja zadania Zając

Object Storage Arubacloud
0 głosów
212 wizyt
pytanie zadane 20 września 2020 w Algorytmy przez wojtek_suchy Mądrala (6,880 p.)

Mam takie zadanie:

Zając

Limit pamięci: 32 MB

Zając Bajtek mieszka na polanie w kształcie prostokąta o wymiarach image metrów. Polana ta jest podzielona na image pól - kwadratów o boku długości image metra. Na niektórych polach znajdują się kopce kreta, które Bajtek zawsze omija.

Każdy skok Bajtka ma długość dokładnie image, a ponieważ Bajtek jest strasznym pedantem - zawsze chce skoczyć dokładnie na środek pola. Tak więc z pola o współrzędnych (image, image) Bajtek może skoczyć tylko na pola o współrzędnych: image, image, image, image, image, image, image lub image, o ile nie wiąże się to z wyskoczeniem poza polanę.

Bajtek chciałby jak najszybciej dotrzeć do swojej nory, nie skacząc na pola, na których znajdują się kopce kreta. Mając dane pole, na którym stoi Bajtek, oraz pole, na którym znajduje się jego nora, pomóż mu obliczyć minimalną liczbę skoków, jakie musi wykonać, aby dotrzeć do nory.

Wejście

W pierwszym wierszu standardowego wejścia znajdują się dwie liczby całkowite image oraz image oddzielone pojedynczym odstępem (image, image), oznaczające rozmiary polany. Kolejne image wierszy zawiera po image znaków oznaczających poszczególne pola polany:

  • "." oznacza wolne pole, czyli takie, na które Bajtek może wskoczyć,
  • "x" oznacza pole, na którym znajduje się kopiec kreta,
  • "z" oznacza pole, na którym obecnie stoi zając Bajtek,
  • "n" oznacza, że na tym polu jest nora Bajtka.

Możesz założyć, że dokładnie jedno pole polany jest oznaczone jako "z" oraz dokładnie jedno pole jest oznaczone jako "n".

 

Wyjście

W pierwszym i jedynym wierszu standardowego wyjścia powinna znaleźć się jedna dodatnia liczba całkowita równa minimalnej liczbie skoków, jakie Bajtek musi wykonać, aby dotrzeć do swojej nory, lub słowo "NIE", jeśli dotarcie Bajtka do nory przy użyciu poprawnych skoków nie jest możliwe.

Przykład

Dla danych wejściowych:

4 5
.zx.x
.xx..
..x.x
x..n.

poprawną odpowiedzią jest:

3

i mam taki kod z bfs który jest niestety za wolny:

#include <bits/stdc++.h>

using namespace std;

int count_jumps(vector<vector<bool>> & glade, pair<int, int> & start_pos, pair<int, int> & end_pos){
    vector<int> dirs = {1,2,  1,-2,  -1,2,  -1,-2,  2,1,  2,-1,  -2,1,  -2,-1};
    queue<pair<int, int>> que;
    set<pair<int, int>> seen;
    int jump_count = 0;
    seen.insert(start_pos);
    que.push(start_pos);
    while (que.size() > 0){
        int que_size = que.size();
        for (int next_pos = 0; next_pos < que_size; next_pos++){
            for (int i = 0; i < dirs.size(); i += 2){
                pair<int, int> new_pos = make_pair(que.front().first + dirs[i], que.front().second + dirs[i+1]);
                if (new_pos.first >= 0 && new_pos.first < glade.size() && new_pos.second >= 0 && new_pos.second < glade[0].size())
                    if (seen.count(new_pos) == 0)
                        if (glade[new_pos.first][new_pos.second]){
                            if (new_pos.first == end_pos.first &&  new_pos.second == end_pos.second)
                                return jump_count + 1;
                            que.push(new_pos);
                            seen.insert(new_pos);
                        }
            }
            que.pop();
        }
        jump_count++;
    }
    return -1;
}

void load_glade(vector<vector<bool>> & glade, pair<int, int> & start_pos, pair<int, int> & end_pos){
    char ch;
    for (int i = 0; i < glade.size(); i++)
        for (int j = 0; j < glade[0].size(); j++){
            cin >> ch;
            if (ch == 'z')
                start_pos = make_pair(i, j);
            else if (ch == 'n' || ch == '.'){
                if (ch == 'n')
                    end_pos = make_pair(i, j);
                glade[i][j] = true;
            }

        }
}
int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(nullptr);
    int n, m, ans;
    pair<int, int> start_pos, end_pos;
    cin >> n >> m;
    vector<vector<bool>> glade(n, vector<bool>(m));
    load_glade(glade, start_pos, end_pos);
    ans = count_jumps(glade, start_pos, end_pos);
    if (ans == -1)
        cout << "NIE";
    else
        cout << ans;
    return 0;
}

czy jest coś nie tak z moją implementacją czy trzeba tutaj użyć czegoś sprytniejszego niż sam bfs?

LINK DO ZADANIA
TUTAJ TESTUJE

1 odpowiedź

+1 głos
odpowiedź 20 września 2020 przez Whistleroosh Maniak (56,980 p.)
wybrane 20 września 2020 przez wojtek_suchy
 
Najlepsza
Zamień seta z linii 8 na vectora booli. Limity w tym zadaniu to coś w okolicy 0.1 sekundy, czyli całkiem mało, więc pozbycie się loga powinno wystarczająco obniżyć złożoność
komentarz 20 września 2020 przez wojtek_suchy Mądrala (6,880 p.)
Dlaczego set jest tak wolny wporówananiu do vectora boolów?
komentarz 20 września 2020 przez Whistleroosh Maniak (56,980 p.)
Set to tak naprawdę balanced binary search tree. A na takich drzewach operacje wstawiania i usuwania zajmują przeważnie O(logn). Zamieniają seta na vector zbijamy złożoność zapytań do O(1), co bardzo usprawnia złożoność całego kodu
komentarz 20 września 2020 przez wojtek_suchy Mądrala (6,880 p.)
kurde, w Pythonie to chyba jest inaczej z set, tam złożoność chyba wynosi około O(1)
komentarz 20 września 2020 przez Whistleroosh Maniak (56,980 p.)
W pythonie set pewnie korzysta z hash table. W c++ jest coś podobnego co nazywa się unordered_set. Taki unordered_set działa właśnie jakoś w O(1)

Podobne pytania

0 głosów
1 odpowiedź 285 wizyt
0 głosów
0 odpowiedzi 308 wizyt
0 głosów
1 odpowiedź 970 wizyt
pytanie zadane 4 kwietnia 2019 w C i C++ przez Alan Kruszyński Obywatel (1,410 p.)

92,555 zapytań

141,403 odpowiedzi

319,557 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!

...