Canyi Chen's Homepage
boolean[] visited = new boolean[N][M]
int step = 0;
int ans = -1;
Queue<int[]> queue = new LinkedList<>();
// queue先放入K的横纵坐标
while(!queue.isEmpty()){
 int sz = queue.size();
 while(sz-- > 0){
  boolean flag = false;
  int[] cur = queue.poll();
  int i = cur[0], j = cur[1];
  if(i < 0 || i >= N || j < 0 || j >=M) continue;
  visited[i][j] = true;
  if(grid[i][j] == '0') continue;
  if(grid[i][j] == 'T'){
   ans = step;
   flag = true;
   break;
  }
  if(j + 1 < M && grid[i][j + 1] != '0'){
    queue.offer(new int[]{i - 1, j + 2});
    queue.offer(new int[]{i + 1, j + 2});
  }
  if(j - 1 >= 0 && grid[i][j - 1] != '0'){
    queue.offer(new int[]{i - 1, j - 2});
    queue.offer(new int[]{i + 1, j - 2});
  }
  if(i + 1 < N && grid[i + 1][j] != '0'){
    queue.offer(new int[]{i + 2, j + 1});
    queue.offer(new int[]{i + 2, j - 1});
  }
  if(i - 1 >= 0 && grid[i - 1][j] != '0'){
    queue.offer(new int[]{i - 2, j - 1});
    queue.offer(new int[]{i - 2, j + 1});
  }
 }
 if(flag) break;
 step++;
}
System.out.println(ans);
constexpr static int direction[8][2] = { //可达位置
    {-2,-1},
    {-1,-2},
    {-2,1},
    {-1,2},
    {1,-2},
    {1,2},
    {2,-1},
    {2,1},
};

constexpr static int directionK[4][2] = { //别脚石可处位置
    {-1,0},
    {1,0},
    {0,-1},
    {0,1},
};

void handler() {
    int t;
    cin >> t;
    for (int index = 0; index < t; ++index) {
        int n, m;
        cin >> n >> m;
        vector<vector<char>> grid(n, vector<char>(m, 1)); //棋盘
        vector<vector<int>> visited(n, vector<int>(m, 0)); //访问标记
        int countG = 0; //草地格子数量
        queue<pair<int, int>> q; //BFS辅助队列
        for (int i = 0; i < n; ++i) { //输入
            for (int j = 0; j < m; ++j) {
                cin >> grid[i][j];
                if (grid[i][j] == 'K' || grid[i][j] == 'T' || grid[i][j] == '1') {
                    ++countG;
                }
                if (grid[i][j] == 'K') {
                    q.emplace(make_pair(i, j));
                    ++visited[i][j];
                }
            }
        }
        if (countG <= 2) { //草地数量不足则返回负一
            cout << -1 << endl;
            continue;
        }
        int ans = 0, size = 1, count = 0;
        bool canFind = false; //标记是否可达目的地
        while (!q.empty()) {
            auto& [i, j] = q.front();
            set<pair<int, int>> untouchble; //记录因别脚石影响不可达的位置
            for (const auto& [iOfs, jOfs] : directionK) {
                int x = i + iOfs, y = j + jOfs;
                if (x >= 0 && x < n && y >= 0 && y < m && grid[x][y] == '0') {
                    if (iOfs == -1 && jOfs == 0) {
                        untouchble.insert(make_pair(i - 2, j - 1));
                        untouchble.insert(make_pair(i - 2, j + 1));
                    }
                    else {
                        if (iOfs == 1 && jOfs == 0) {
                            untouchble.insert(make_pair(i + 2, j - 1));
                            untouchble.insert(make_pair(i + 2, j + 1));
                        }
                        else {
                            if (iOfs == 0 && jOfs == -1) {
                                untouchble.insert(make_pair(i - 1, j - 2));
                                untouchble.insert(make_pair(i + 1, j - 2));
                            }
                            else {
                                untouchble.insert(make_pair(i - 1, j + 2));
                                untouchble.insert(make_pair(i + 1, j + 2));
                            }
                        }
                    }
                }
            }
            for (const auto& [iOfs, jOfs] : direction) {
                int x = i + iOfs, y = j + jOfs;
                if (x >= 0 && x < m && y >= 0 && y < n && //在表格范围内 
                    visited[x][y] != 1 && //未访问过
                    grid[x][y] != '0' && //不是石头
                    !untouchble.count(make_pair(x, y))) { //没被别马脚
                    ++visited[x][y];
                    if (grid[x][y] == 'T') {
                        canFind = true;
                        goto L;
                    }
                    q.emplace(make_pair(x, y));
                }
            }
            q.pop();
            ++count;
            if (count == size) {
                size = q.size();
                count = 0;
                ++ans;
            }
        }
    L:
        if (canFind) {
            cout << ++ans << endl;
        }
        else {
            cout << -1 << endl;
        }
    }
}