[USACO05DEC] Knights of Ni S

[USACO05DEC] Knights of Ni S

一道很水的搜索, 由于不想做题, 只能写写水题来放松一下了.

分别以贝茜和骑士为起点跑 BFS, 求出到每个灌木的最短距离, 然后枚举一遍取最小值就行了.

code:

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;

inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  for (; !isdigit(ch); ch = getchar()) if (ch == '-') f = -1;
  for (; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + (ch ^ 48);
  return x * f;
}

struct Node {
  int x, y;

  inline Node (int a, int b) {
    x = a, y = b;
  }

  inline Node operator + (const Node &a) const {
    return Node(x + a.x, y + a.y);
  }
};

const int N = 1e3 + 5;
int n, m, s[N][N], d1[N][N], d2[N][N], ans = 1 << 30;
Node st = Node(0, 0), ed = Node(0, 0), tmp[4] = {Node(-1, 0), Node(0, -1), Node(0, 1), Node(1, 0)};
queue <Node> q;
bool vis[N][N];

int main() {
  m = read(), n = read();
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      s[i][j] = read();
      if (s[i][j] == 2) st = Node(i, j);
      else if (s[i][j] == 3) ed = Node(i, j);
    }
  }
  memset(d1, 0x3f, sizeof(d1));
  memset(d2, 0x3f, sizeof(d2));
  d1[st.x][st.y] = d2[ed.x][ed.y] = 0;
  q.push(st);
  vis[st.x][st.y] = 1;
  while (q.size()) {
    Node x = q.front(); q.pop();
    for (int i = 0; i < 4; i++) {
      Node y = x + tmp[i];
      if (vis[y.x][y.y]) continue;
      if (s[y.x][y.y] == 1 || s[y.x][y.y] == 3) continue;
      if (y.x < 1 || y.x > n || y.y < 1 || y.y > m) continue;
      vis[y.x][y.y] = 1;
      q.push(y);
      d1[y.x][y.y] = d1[x.x][x.y] + 1;
    }
  }
  memset(vis, 0, sizeof(vis));
  q.push(ed);
  vis[ed.x][ed.y] = 1;
  while (q.size()) {
    Node x = q.front(); q.pop();
    for (int i = 0; i < 4; i++) {
      Node y = x + tmp[i];
      if (vis[y.x][y.y]) continue;
      if (s[y.x][y.y] == 1) continue;
      if (y.x < 1 || y.x > n || y.y < 1 || y.y > m) continue;
      vis[y.x][y.y] = 1;
      q.push(y);
      d2[y.x][y.y] = d2[x.x][x.y] + 1;
    }
  }
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      if (s[i][j] == 4) ans = min(ans, d1[i][j] + d2[i][j]);
    }
  }
  printf("%d\n", ans);
  return 0;
} 
posted @ 2021-10-27 21:36  sshadows  阅读(37)  评论(0编辑  收藏  举报