one time bfs + priority_queue c++ (explaination included)
when we mark as visit we need two coords, box and keeper.\nbecause they all <= 20, so I just use 100 , and easy for debug,\nmy algorith first work on keeper min
when we mark as visit we need two coords, box and keeper.\nbecause they all <= 20, so I just use 100 , and easy for debug,\nmy algorith first work on keeper minimized moves, but the mini push is asked so have to use pq to pop min pushes.\n\n```\nclass Solution {\npublic:\n    int minPushBox(vector<vector<char>>& grid) {\n\t    // remember three coords, and retore them to not \'#\' it is road not wall\n        int row = grid.size(), col = grid.front().size();\n        pair<int, int> t, b, s;\n        for (int r = 0; r < row; ++r) {\n            for (int c = 0; c < col; ++c) {\n                if (grid[r][c] == \'T\') {\n                    t = make_pair(r, c);\n                    grid[r][c] = \'.\';\n                }\n                if (grid[r][c] == \'B\') {\n                    b = make_pair(r, c);\n                    grid[r][c] = \'.\';\n                }\n                if (grid[r][c] == \'S\')  {\n                    s = make_pair(r, c);\n                    grid[r][c] = \'.\';\n                }\n            }\n        }\n        priority_queue<pair<int, int>, vector<pair<int,int>>, greater<pair<int,int>>> q;\n        unordered_set<int> vi;\n\t\t// step is pushes, and key contains two coords\n        q.emplace(0, b.first * 1000000 + b.second * 10000 + s.first * 100 + s.second);\n        vi.emplace(b.first * 1000000 + b.second * 10000 + s.first * 100 + s.second);\n\n\t\t// just helper function to get cell\n        auto g = [&](int r, int c) {\n            if (r < 0 || r >= row || c < 0 || c >= col) return \'#\';\n            return grid[r][c];\n        };\n\n\t\t// if keeper possible moves\n        auto check = [&](int step, int br, int bc, int r, int c) {\n            if (g(r, c) != \'.\') return;\n            if (br == r && bc == c) return;\n            int key = br * 1000000 + bc * 10000 + r * 100 + c;\n            if (vi.count(key)) return;\n            vi.emplace(key);\n            q.emplace(step, key);\n        };\n\n\t\t// if push is possible, we need +1 on steps if possible\n        auto push = [&](int step, int br, int bc, int r, int c) {\n            int key = -1;\n            if (make_pair(r + 1, c) == make_pair(br, bc) && g(r + 2, c) == \'.\') {\n                key = (br + 1) * 1000000 + bc * 10000 + (r + 1)  * 100 + c;\n            } else if (make_pair(r - 1, c) == make_pair(br, bc) && g(r - 2, c) == \'.\') {\n                key = (br - 1) * 1000000 + bc * 10000 + (r - 1) * 100 + c;\n            } else if (make_pair(r, c + 1) == make_pair(br, bc) && g(r, c + 2) == \'.\') {\n                key = br * 1000000 + (bc + 1) * 10000 + r * 100 + c + 1;\n            } else if (make_pair(r, c - 1) == make_pair(br, bc) && g(r, c - 2) == \'.\') {\n                key = br * 1000000 + (bc - 1) * 10000 + r * 100 + c - 1;\n            }\n            if (key == -1) return;\n            if (vi.count(key)) return;\n            vi.emplace(key);\n            q.emplace(step + 1, key);\n        };\n\t\t// here is just simple bfs\n        while (q.size()) {\n            int step = q.top().first;\n            int cbr = q.top().second / 1000000 % 100;\n            int cbc = q.top().second / 10000 % 100;\n            int csr = q.top().second / 100 % 100;\n            int csc = q.top().second / 1 % 100;\n            q.pop();\n            if (cbr == t.first && cbc == t.second) return step;\n            check(step, cbr, cbc, csr + 1, csc);\n            check(step, cbr, cbc, csr, csc + 1);\n            check(step, cbr, cbc, csr - 1, csc);\n            check(step, cbr, cbc, csr, csc - 1);\n            push(step, cbr, cbc, csr, csc);\n        }\n        return -1;\n    }\n};
[]