Cerința
Eroul nostru Susan se află într-un turn de formă cubică, de latură n
. El dorește să ajungă la comoara ascunsă în interiorul turnului. Din fericire, Susan a făcut rost de o hartă care îi indică cu exactitate coordonatele locului în care se află comoara din turn. Eroul nostru vrea să știe care este distanța minimă pe care o poate parcurge pentru a ajunge la comoară.
Turnul este împărțit în n
etaje, iar fiecare etaj este împărțit în n x n
celule (camere). O cameră poate:
- fi blocată, astfel fiind inaccesibilă eroului nostru
- fi accesibilă, astfel eroul nostru poate intra în aceasta
- conține o scară ascendentă care îl poate duce pe erou cu un etaj mai sus, în camera situată deasupra camerei curente
- conține o scară descendentă care îl poate duce pe erou cu un etaj mai jos, în camera situată sub camera curentă
- conține o trapă prin care eroul va cădea la etajul inferior, în camerele situate sub camera curentă (dacă eroul, în urma căderii, se află într-o cameră ce conține o trapă, el va continua să cadă până se va afla într-o o cameră fără trapă, pe aceeași coloană)
La fiecare trecere dintr-o cameră în alta, eroul execută un pas.
Fiind date latura turnului și coordonatele zidurilor, scărilor, gropilor, eroului și a comorii, se cere să se afișeze numărul minim de pași pe care îl poate parcurge Susan pentru a ajunge la comoară.
Date de intrare
Fișierul de intrare turn.in
conține:
Exemplu
turn.in
3 9 3 3 3 1 1 3 1 2 1 1 3 2 2 1 1 2 1 3 2 2 2 3 1 1 3 2 3 3 3 3 1 2 3 2 3 2 2 1 2 2 2 3 3 3 2 3 1 2 3 3 1 3 2 1 2 3 1 1 1 1 2 2 1
turn.out
11
Explicație
Turnul are 3
etaje. Susan pleacă din celula de coordonate (1 1 1)
, iar celula în care se află comoara are coordonatele (2 2 1)
. Există 9
celule în care se află ziduri, 3
celule în care se află scări ascendente, 3
celule în care se află scări descendente și 3
celule în care se află gropi. Traseul cel mai scurt trece prin 11
camere: (1 1 1) (1 1 2) (1 2 2) (1 2 3) (2 2 3) (2 3 3) (2 3 2) (3 3 2) (3 2 2) (3 2 1) (2 2 1)
.
#include <bits/stdc++.h> using namespace std; ifstream cin("turn.in"); ofstream cout("turn.out"); struct poz { int i , j , k; }; const int dj[] = {-1 , 1 , 0 , 0}; const int dk[] = { 0 , 0 , -1 , 1}; int n , x1 , y1 , z1 , x2 , y2 , z2 , m , p , qu , r; int a[101][101][101]; int b[101][101][101]; queue < poz > q; int inside(int i , int j , int k) { return i >= 1 && i <= n && j >= 1 && j <= n && k >= 1 && k <= n; } void lee() { b[x1][y1][z1]=1; poz r; r.i = x1 , r.j = y1 , r.k = z1; while(!q.empty()) { poz r; r = q.front(); if(a[r.i][r.j][r.k] == -4) { int inou = r.i; if(a[inou][r.j][r.k] == -4 && inou > 1) inou--; if(inside(inou , r.j , r.k) && a[inou][r.j][r.k] != -1 && b[inou][r.j][r.k] == 0) { q.push({inou , r.j , r.k}); b[inou][r.j][r.k] = b[r.i][r.j][r.k] + 1; } } else { if(a[r.i][r.j][r.k] == -2) { int inou = r.i + 1; if(inside(inou , r.j , r.k) && a[inou][r.j][r.k] != -1 && b[inou][r.j][r.k] == 0) { q.push({inou , r.j , r.k}); b[inou][r.j][r.k] = b[r.i][r.j][r.k] + 1; } } else if(a[r.i][r.j][r.k] == -3) { int inou = r.i - 1; if(inside(inou , r.j , r.k) && a[inou][r.j][r.k] != -1 && b[inou][r.j][r.k] == 0) { q.push({inou , r.j , r.k}); b[inou][r.j][r.k] = b[r.i][r.j][r.k] + 1; } } for(int d = 0 ; d < 4 ; d++) { int inou = r.i; int jnou = r.j + dj[d]; int knou = r.k + dk[d]; if(inside(inou , jnou , knou) && a[inou][jnou][knou] != -1 && b[inou][jnou][knou] == 0) { q.push({inou , jnou , knou}); b[inou][jnou][knou] = b[r.i][r.j][r.k] + 1; } } } q.pop(); } } int main() { cin >> n >> m >> p >> qu >> r; int x,y,z; for(int i = 1 ; i <= m ; i++) { cin >> x >> y >> z; a[x][y][z] = -1; } for(int i = 1 ; i <= p ; i++) { cin >> x >> y >> z; a[x][y][z] = -2; } for(int i = 1 ; i <= qu ; i++) { cin >> x >> y >> z; a[x][y][z] = -3; } for(int i = 1 ; i <= r ; i++) { cin >> x >> y >> z; a[x][y][z] = -4; } cin >> x1 >> y1 >> z1 >> x2 >> y2 >> z2; q.push({x1 , y1 , z1}); lee(); cout << b[x2][y2][z2]; return 0; }