牛校出牛子,牛子刷牛客

#include<iostream>
#include<unordered_set>
#include<vector>
#include<queue>
using namespace std;
unordered_set<int> visited;
int n, m;
vector<vector<int>> direct = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
vector<vector<char>> graph;
struct node{
    int xp, yp, xb, yb, s;
    node(int xxp, int yyp, int xxb, int yyb, int ss){
        xp = xxp, yp = yyp, xb = xxb, yb = yyb, s = ss;
    }
};
bool valid(vector<int> dir, node cur, int n, int m){
    int x = dir[0] + cur.xp, y = dir[1] + cur.yp;
    int xxb = cur.xb, yyb = cur.yb;
    if(x == cur.xb && y == cur.yb){
        xxb += dir[0], yyb += dir[1];
    }
    if(x >= n || y >= m || x < 0 || y < 0 || xxb >= n || yyb >= m || xxb < 0 || yyb < 0){
        return false;
    }
    else if(graph[x][y] == '#' || graph[xxb][yyb] == '#'){
        return false;
    }
    else if(visited.find(x + y * 100 + xxb * 10000 + yyb * 1000000) != visited.end()){
        return false;
    }
    return true;
}
int main(){
    int n, m;
    cin >> n >> m;
    graph = vector<vector<char>>(n, vector<char>(m));
    int xbox, ybox, xs, ys, xe, ye;
    for(int i = 0; i < n; ++i){
        for(int j = 0; j < m; ++j){
            cin >> graph[i][j];
            if(graph[i][j] == '0'){
                xbox = i, ybox = j;
                graph[i][j] = '.';
            }
            else if(graph[i][j] == 'S'){
                xs = i, ys = j;
                graph[i][j] = '.';
            }
            else if(graph[i][j] == 'E'){
                xe = i, ye = j;
            }
        }
    }
    queue<node> q;
    auto p = node(xs, ys, xbox, ybox, 0);
    visited.insert(xs + ys * 100 + xbox * 10000 + ybox * 1000000);
    q.push(p);
    int ans = -1;
    while(!q.empty()){
        node cur = q.front();
        q.pop();
        if(cur.xb == xe && cur.yb == ye){
            ans = cur.s;
            break;
        }
        for(int i = 0; i < 4; ++i){
            if(!valid(direct[i], cur, n, m)){
                continue;
            }
            int xn = cur.xp + direct[i][0], yn = cur.yp + direct[i][1];
            int xbn = cur.xb, ybn = cur.yb;
            if(xn == cur.xb && yn == cur.yb){
                xbn += direct[i][0], ybn += direct[i][1];
            }
            visited.insert(xn + yn * 100 + xbn * 10000 + ybn * 1000000);
            q.push(node(xn, yn, xbn, ybn, cur.s + 1));
        }
    }
    cout << ans << endl;
}