HDU-4528 小明系列故事-捉迷藏(BFS)
阿新 • • 發佈:2020-07-24
分析:我們可以預處理出從'D','E'往四個方向,能被其它格子看到的座標。然後用一個狀態陣列標記走過的格子,即\(st[pos.y][pos.x][d][e]\),前兩維表示走過的格子,第三維表示是否看到大明,第四維表示是否能看到二明。
#include <iostream> #include <cstdio> #include <cstring> #include <string> #include <vector> #include <queue> #include <algorithm> using namespace std; using PII = pair<int, int>; const int N = 105; char g[N][N]; //小明,大明,二明 PII s, e, d; //每個點是否能看到大明、二明 bool look[N][N][2]; int dx[] = { -1, 1, 0, 0 }; int dy[] = { 0, 0, -1, 1 }; int n, m, time; char id[2] = { 'D', 'E' }; struct Node { int y, x; int step; bool d, e; }; bool st[N][N][2][2]; void test_look(PII pos, int type) { for (int i = 0; i < 4; ++i) { int ny = pos.first, nx = pos.second; while (true) { ny += dy[i], nx += dx[i]; if (g[ny][nx] == 'X' || g[ny][nx] == id[1 - type]) break; if (ny < 1 || ny > n || nx < 1 || nx > m) break; look[ny][nx][type] = true; } } } int bfs() { memset(st, 0, sizeof st); queue<Node> q; Node p; p.step = 0, p.d = false, p.e = false; p.y = s.first, p.x = s.second; if (look[s.first][s.second][0]) p.d = true; if (look[s.first][s.second][1]) p.e = true; q.push(p); while (q.size()) { Node p = q.front(); q.pop(); if (p.d && p.e) return p.step; if (p.step > time) return -1; for (int i = 0; i < 4; ++i) { Node now = p; now.y += dy[i]; now.x += dx[i]; ++now.step; if (now.y < 1 || now.y > n || now.x < 1 || now.x > m) continue; if (g[now.y][now.x] == 'X' || g[now.y][now.x] == 'E' || g[now.y][now.x] == 'D') continue; if (look[now.y][now.x][0]) now.d = true; if (look[now.y][now.x][1]) now.e = true; if (st[now.y][now.x][now.d][now.e]) continue; st[now.y][now.x][now.d][now.e] = true; q.push(now); } } return -1; } int main() { int t; scanf("%d", &t); int c = 0; while (t--) { scanf("%d%d%d", &n, &m, &time); for (int i = 1; i <= n; ++i) scanf("%s", *(g + i) + 1); for (int i = 1; i <= n; ++i) { for (int j = 1; j <= m; ++j) { if (g[i][j] == 'S') { s = make_pair(i, j); } if (g[i][j] == 'D') { d = make_pair(i, j); } if (g[i][j] == 'E') { e = make_pair(i, j); } } } memset(look, 0, sizeof look); test_look(d, 0); test_look(e, 1); int res = bfs(); printf("Case %d:\n%d\n", ++c, res); } return 0; }
畫個豌豆射手:(以後每天畫幾個畫素畫,掛部落格上)