#include #include #include #include #include #include #include #include #include using namespace std; struct Point { Point() {} Point(const Point& cp) { x = cp.x; y = cp.y; } Point(int a, int b) { x = a; y = b; } bool operator <(const Point& b) const { if(x != b.x) return x < b.x; return y < b.y; } int x,y; }; int m, n; int input[80][80]; int cost[81][81]; Point src, dest; set up; inline bool CanPass(const Point& a, const Point& b) { if(a.x < 0 || a.x > m || a.y < 0 || a.y > n || b.x < 0 || b.x > m || b.y < 0 || b.y > n){ return false; } if(a.x == b.x) { int y = min(a.y, b.y); if(a.x <= 0 || a.x >= m) return true; return input[a.x][y] == 0 || input[a.x-1][y] == 0; } else { int x = min(a.x, b.x); if(a.y <= 0 || a.y >= n) return true; return input[x][a.y] == 0 || input[x][a.y-1] == 0; } } void Update(int x, int y, int c) { if(x < 0 || x > m || y < 0 || y > n) return; if(cost[x][y] < c) { cost[x][y] = c; up.insert(Point(x,y)); } } void CalcCost() { up.clear(); memset(cost, 0, sizeof(cost)); for(int i = 0; i < m; ++i) for(int j = 0; j < n; ++j) { if(input[i][j]) { Update(i, j, m+n); Update(i+1, j, m+n); Update(i, j+1, m+n); Update(i+1, j+1, m+n); } } while(!up.empty()) { Point p = *up.begin(); up.erase(up.begin()); int c = cost[p.x][p.y] - 1; Update(p.x+1, p.y, c); Update(p.x-1, p.y, c); Update(p.x, p.y+1, c); Update(p.x, p.y-1, c); } } int search(Point from, Point to){ int pathcost[81][81]; for(int i=0; i<81; i++){ for(int j=0; j<81; j++){ pathcost[i][j] = INT_MAX; } } priority_queue > next; pathcost[from.x][from.y] = cost[from.x][from.y]; next.push(make_pair(-cost[from.x][from.y], from)); while(next.size() > 0){ pair pr = next.top(); Point p = pr.second; next.pop(); if(p.x == to.x && p.y == to.y){ return pathcost[to.x][to.y]; } Point q; int c; q = Point(p.x-1, p.y); if(CanPass(p,q)){ c = pathcost[p.x][p.y] + cost[q.x][q.y]; if(c < pathcost[q.x][q.y]){ pathcost[q.x][q.y] = c; next.push(make_pair(-c, q)); } } q = Point(p.x+1, p.y); if(CanPass(p,q)){ c = pathcost[p.x][p.y] + cost[q.x][q.y]; if(c < pathcost[q.x][q.y]){ pathcost[q.x][q.y] = c; next.push(make_pair(-c, q)); } } q = Point(p.x, p.y-1); if(CanPass(p,q)){ c = pathcost[p.x][p.y] + cost[q.x][q.y]; if(c < pathcost[q.x][q.y]){ pathcost[q.x][q.y] = c; next.push(make_pair(-c, q)); } } q = Point(p.x, p.y+1); if(CanPass(p,q)){ c = pathcost[p.x][p.y] + cost[q.x][q.y]; if(c < pathcost[q.x][q.y]){ pathcost[q.x][q.y] = c; next.push(make_pair(-c, q)); } } } return -1; } int main() { ifstream cin("erythea.txt"); int M; cin >> M; for(int cnt = 0; cnt < M; ++cnt) { cin >> n >> m; cin >> src.y >> src.x; cin >> dest.y >> dest.x; string line; for(int j = 0; j < n; ++j) { cin >> line; for(int i = 0; i < m; ++i) { input[i][j] = line[i] - '0'; } } CalcCost(); /* for(int j = 0; j < n; ++j) { for(int i = 0; i < m; ++i) { cout << cost[i][j] << " "; } cout << endl; } */ cout << search(src, dest) << endl; } }