#include #include #include // Abychom nemuseli psát např. "std::cin" ale jen "cin" using namespace std; int main() { int n, t, start_x, start_y, cil_x, cil_y; // Načteme konstanty ze vstupu cin >> n; cin >> start_x; cin >> start_y; cin >> cil_x; cin >> cil_y; cin >> t; // Vytvoříme pole pro povolené tahy int *tahy_x = new int[t]; int *tahy_y = new int[t]; // Načteme povolené tahy for(int i = 0; i < t; i++) { cin >> tahy_x[i]; cin >> tahy_y[i]; } // Vytvoříme pole, které použijeme při prohledávání do šířky // Pro každý bod si pamatujeme pouze souřadnice místa, z kterého jsme sem dostali int *zpet_x = new int[n * n]; int *zpet_y = new int[n * n]; // Tyto pole vyplníme invalidními hodnotami // Na pole nikdy nepřijdeme ze souřadnic -1, -1 for(int i = 0; i < n * n; i++) { zpet_x[i] = -1; zpet_y[i] = -1; } // Fronta míst, které chceme zpracovat // queue - first-in-first-out - FIFO queue fronta_x; queue fronta_y; // Začínáme startem fronta_x.push(start_x); fronta_y.push(start_y); bool uspech = false; // Běžíme, dokud ve frontě je nějaký prvek while(!fronta_x.empty()) { // Podíváme se na souřadnice na začátku fronty int x = fronta_x.front(); int y = fronta_y.front(); // Posléze je odstraníme fronta_x.pop(); fronta_y.pop(); // Vyzkoušíme všechny možné tahy for(int i = 0; i < t; i++) { // Načteme tah, který právě chceme zkusit int nove_x = x + tahy_x[i]; int nove_y = y + tahy_y[i]; // Pokud tah vede mimo šachovnici, tak ho ignorujeme if(nove_x < 0 || nove_x >= n || nove_y < 0 || nove_y >= n) continue; // Pokud se na výsledné políčko už umíme dostat, přeskočíme tah // -1 je ve zpet_x právě když je i ve zpet_y, tedy stačí zkontrolovat jedno z těchto polí if(zpet_x[nove_y * n + nove_x] != -1) continue; // Na výsledné políčko tahu zapíšeme políčko, ze kterého tam skáčeme, tedy aktuální políčko zpet_x[nove_y * n + nove_x] = x; zpet_y[nove_y * n + nove_x] = y; // A výsledné políčko přidáme do fronty fronta_x.push(nove_x); fronta_y.push(nove_y); // Pokud je výsledné políčko zároveň cílem, nalezli jsme nejrychlejší cestu ze startu do cíle if(nove_x == cil_x && nove_y == cil_y) { uspech = true; break; } } // Pokud už jsme nalezli nejkratší cestu, nemá smysl ve smyčce pokračovat if(uspech) break; } // Pro případ, že žádnou cestu do startu nenalezneme if(!uspech) { cout << "Chyba! Cesta ze startu do cile pro tyto tahy neexistuje!"; } else { // Protože si pro každé políčko pamatujeme jen to, z kterého jsme na něj přišli, // umíme cestu rekostruovat jen pozpátku. int x = cil_x; int y = cil_y; // Souřadnice políček cesty při průchodu pozpátku si tedy budeme ukládat do zásobníku // První prvek přidaný do zásobníku můžeme přečíst jen jako poslední // Zásobník nám vlastně obrátí pořadí políček stack cesta_x; stack cesta_y; while(x != start_x || y != start_y) { cesta_x.push(x); cesta_y.push(y); // Index si spočítáme předem // Kdybychom to v tomto případě neudělali, proměnná x by se nám změnila a y bychom poté přečetli ze špatného indexu int i = y * n + x; x = zpet_x[i]; y = zpet_y[i]; } // Vypíšeme délku cesty int delka = cesta_x.size(); cout << delka; cout << '\n'; // Zásobník s cestou obsahuje i políčko cíle, které vypisovat nechceme, proto vypíšeme jen delka - 1 záznamů for(int i = 0; i < delka - 1; i++) { // Vypíšeme políčko cesty (včetně mezery mezi čísly a znaku nového řádku) cout << cesta_x.top(); cout << ' '; cout << cesta_y.top(); cout << '\n'; // A vypsané políčko ze zásobníku odstraníme cesta_x.pop(); cesta_y.pop(); } } return 0; }