Grade 11 · BacktrackingCitește în română
Paths in a maze
Original: Drumuri într-un labirint
The idea
The maze is an n × m matrix of 0 (free) and 1 (wall). We start in the top-left corner (1, 1) and want to reach the bottom-right corner (n, m), moving up, down, left or right, without passing through the same cell twice. From every cell we try the 4 directions; we mark the cell as visited on the way in and unmark it on the way back. The number of paths and the length of the shortest one (in cells) are printed, or 0 if there is no path.
Original description (Romanian)
Labirintul este o matrice n × m cu 0 (liber) și 1 (zid). Pornim din colțul stânga-sus (1, 1) și vrem să ajungem în colțul dreapta-jos (n, m), mergând sus, jos, stânga sau dreapta, fără să trecem de două ori prin aceeași celulă. Din fiecare celulă încercăm cele 4 direcții; marcăm celula ca vizitată la intrare și o demarcăm la întoarcere. Se afișează numărul de drumuri și lungimea celui mai scurt (în celule), sau 0 dacă nu există drum.
- Complexity
- exponential (the number of paths can be very large)
- Grade
- Grade 11 (Clasa a XI-a)
- Chapter
- Backtracking
Examples
Input
3 3 0 0 0 0 1 0 0 0 0
Expected output
Drumuri: 2 Cel mai scurt: 5
The code
Comments are in Romanian, as in the original collection. Edit freely: you can reset at any time.
/*
* Titlu: Drumuri într-un labirint
* Clasa: 11
* Capitol: Metoda backtracking
* Descriere: Labirintul este o matrice n × m cu 0 (liber) și 1 (zid). Pornim din colțul
* stânga-sus (1, 1) și vrem să ajungem în colțul dreapta-jos (n, m), mergând
* sus, jos, stânga sau dreapta, fără să trecem de două ori prin aceeași celulă.
* Din fiecare celulă încercăm cele 4 direcții; marcăm celula ca vizitată la
* intrare și o demarcăm la întoarcere. Se afișează numărul de drumuri și
* lungimea celui mai scurt (în celule), sau 0 dacă nu există drum.
* Complexitate: exponențială (numărul de drumuri poate fi foarte mare)
*
* Exemplu
* Intrare:
* 3 3
* 0 0 0
* 0 1 0
* 0 0 0
* Ieșire:
* Drumuri: 2
* Cel mai scurt: 5
*/
#include <iostream>
using namespace std;
int n, m, a[12][12], drumuri = 0, minim = 1000;
bool vizitat[12][12];
int dl[4] = {-1, 0, 1, 0};
int dc[4] = {0, 1, 0, -1};
void back(int l, int c, int lungime)
{
if (l == n && c == m)
{
drumuri++;
if (lungime < minim)
{
minim = lungime;
}
return;
}
for (int d = 0; d < 4; d++)
{
int nl = l + dl[d], nc = c + dc[d];
if (nl >= 1 && nl <= n && nc >= 1 && nc <= m && a[nl][nc] == 0 && !vizitat[nl][nc])
{
vizitat[nl][nc] = true;
back(nl, nc, lungime + 1);
vizitat[nl][nc] = false;
}
}
}
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
cin >> a[i][j];
}
}
if (a[1][1] == 0)
{
vizitat[1][1] = true;
back(1, 1, 1);
}
cout << "Drumuri: " << drumuri << '\n';
cout << "Cel mai scurt: " << (drumuri > 0 ? minim : 0) << '\n';
return 0;
}
Runs on a real g++ (C++17, -O2) through Compiler Explorer. Keep runs short; there's a time limit.