1. 程式人生 > 實用技巧 >Nightmare Ⅱ

Nightmare Ⅱ

題目連結:https://vjudge.net/problem/HDU-3085

題意:有兩個鬼Z,他們沒秒會佔領離他的距離小於等於2的位置,有男孩M和女孩G,男孩每秒走3個單位,女孩走1個單位。每次都是鬼先覆蓋,再男孩,女孩走。問男孩女孩能否相遇,如果可以則輸出所需最小時間,否則輸出-1;

思路:對男孩女孩進行雙向bfs即可。但要注意鬼先覆蓋,可能直接就殺手男孩和女孩了。

//#include<bits/stdc++.h>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include
<algorithm> #include<queue> using namespace std; typedef long long ll; #define INF 0x7ffffff const int N = 805; int n, m, vis[N][N]; int zx1, zy1, zx2, zy2, mx, my, gx, gy, step; char G[N][N]; int dx[4] = {0, 1, 0, -1}; int dy[4] = {1, 0, -1, 0}; struct node { int x, y; node(int xx, int
yy) { x = xx; y = yy; ; } }; bool ok(int x, int y) { if (x < 0 || y < 0 || x >= n || y >= m || G[x][y] == 'X') return false; //看能不能被鬼覆蓋 if (abs(x - zx1) + abs(y - zy1) <= 2 * step) return false; if (abs(x - zx2) + abs(y - zy2) <= 2
* step) return false; return true; } int bfs() { memset(vis, 0, sizeof(vis)); //標記狀態 0表示未訪問 1表示男孩 2表示女孩訪問 vis[mx][my] = 1; vis[gx][gy] = 2; step = 0; //初始化時間 queue<node> qm, qg; qm.push(node(mx, my)); qg.push(node(gx, gy)); while (!qm.empty() && !qg.empty()) { step++; //男孩走3步 for (int k = 0; k < 3; k++) { for (int i = 0, len = qm.size(); i < len; i++) { node t = qm.front(); qm.pop(); //判斷一下剛出來的點是否能動 if (!ok(t.x, t.y)) continue; for (int j = 0; j < 4; j++) { int fx = t.x + dx[j]; int fy = t.y + dy[j]; if (!ok(fx, fy) || vis[fx][fy] == vis[t.x][t.y]) continue; //看該點符合要求否 避免重複走 if (vis[fx][fy] + vis[t.x][t.y] == 3) { //找到答案 return step; } vis[fx][fy] = vis[t.x][t.y]; qm.push(node(fx, fy)); } } } //女孩走一步 for (int i = 0, len = qg.size(); i < len; i++) { node t = qg.front(); qg.pop(); if (!ok(t.x, t.y)) continue; for (int j = 0; j < 4; j++) { int fx = t.x + dx[j]; int fy = t.y + dy[j]; if (!ok(fx, fy) || vis[fx][fy] == vis[t.x][t.y]) continue; if (vis[fx][fy] + vis[t.x][t.y] == 3) { //找到答案 return step; } vis[fx][fy] = vis[t.x][t.y]; qg.push(node(fx, fy)); } } } return -1; } int main() { int t; cin>>t; while (t--) { cin>>n>>m; for (int i = 0; i < n; i++) { scanf("%s", G[i]); } //找出男女鬼的位置 int cnt = 0; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (G[i][j] == 'Z') { if (!cnt) { zx1 = i; zy1 = j; cnt++; } else { zx2 = i; zy2= j; } } if (G[i][j] == 'M') mx = i, my = j; if (G[i][j] == 'G') gx = i, gy = j; } } printf("%d\n", bfs()); } return 0; }