题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3533
需要注意的点:
1,人不能去有城堡的地方
2,子弹不能穿过城堡,遇到城堡子弹不会继续向前射,即使城堡在途中也不行,比如说子弹从(0, 0) 向 (0, 3)射,如果(0, 1)有城堡,子弹会消失。
3,子弹是从时间 t 开始射击的,不是从0开始。
思路就是人先走,然后遍历每一个城堡的射击时间,如果到了射击时间,就把这个城堡的子弹放入队列里面。然后注意一些限制条件即可。判断子弹是否在射击途中遇到城堡,如果没有就放入队列里面,弹出的子弹记得在那个位置减去一个子弹,表示这个子弹已经离开这个位置了。
#include <iostream>
#include <queue>
#include <cstring>
#include <string>
#include <map>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
const int INF = 0x3f3f3f3f;
const int Maxn = 4e5+10;
struct Shot {
char dir;
int i, j, v, t;
} shot[105];
struct Node {
int i, j, step;
};
int N, M, gun, ener, dir[4][2] = { {1, 0}, {-1, 0},
{0, 1}, {0, -1} }, G[105][105];
bool vis[105][105];
void print() {
for(int i = 0; i <= N; ++i) {
for(int j = 0; j <= M; ++j)
cout << G[i][j] << " ";
cout << endl;
}
cout << endl;
}
void bfs() {
memset(vis, 0, sizeof(vis));
queue<Node> quP;
queue<Shot> quS;
Node Ntmp; Shot Stmp;
Ntmp.i = 0; Ntmp.j = 0; Ntmp.step = 0;
quP.push(Ntmp);
vis[0][0] = true;
while (!quP.empty()) {
int cnt = quP.size(), curtime;
while (cnt--) {
Ntmp = quP.front(); quP.pop();
curtime = Ntmp.step+1;
if(Ntmp.i == N && Ntmp.j == M) {
printf("%d\n", Ntmp.step); return;
}
for(int i = 0; i < 4; ++i) {
Node now = Ntmp;
now.i += dir[i][0]; now.j += dir[i][1];
if(now.i < 0 || now.i > N || now.j < 0 || now.j > M
|| vis[now.i][now.j] || G[now.i][now.j] == -1 || G[now.i][now.j] > 0) continue;
now.step++;
if(now.step > ener) continue;
vis[now.i][now.j] = true;
quP.push(now);
}
if(Ntmp.step+1 < ener && G[Ntmp.i][Ntmp.j] == 0) {
Ntmp.step++; quP.push(Ntmp);
}
}
for(int i = 0; i < gun; ++i)
if(curtime % shot[i].t == 0) quS.push(shot[i]);
cnt = quS.size();
while(cnt--) {
Stmp = quS.front(); quS.pop();
if(G[Stmp.i][Stmp.j] > 0)
G[Stmp.i][Stmp.j]--;
Shot now = Stmp;
if(now.dir == 'N' && now.i-now.v >= 0) {
now.i -= now.v;
bool ok = true;
for(int i = Stmp.i-1; i >= now.i; --i) if(G[i][now.j] == -1) ok = false;
if(ok) {
G[now.i][now.j]++;
quS.push(now);
}
}
now = Stmp;
if(now.dir == 'S' && now.i+now.v <= N) {
now.i += now.v;
bool ok = true;
for(int i = Stmp.i+1; i <= now.i; ++i) if(G[i][now.j] == -1) ok = false;
if(ok) {
G[now.i][now.j]++;
quS.push(now);
}
}
now = Stmp;
if(now.dir == 'W' && now.j-now.v >= 0) {
now.j -= now.v;
bool ok = true;
for(int j = Stmp.j-1; j >= now.j; --j) if(G[now.i][j] == -1) ok = false;
if(ok) {
G[now.i][now.j]++;
quS.push(now);
}
}
now = Stmp;
if(now.dir == 'E' && now.j+now.v <= M) {
now.j += now.v;
bool ok = true;
for(int j = Stmp.j+1; j <= now.j; ++j) if(G[now.i][j] == -1) ok = false;
if(ok) {
G[now.i][now.j]++;
quS.push(now);
}
}
}
// print();
}
printf("Bad luck!\n");
}
int main(void)
{
while(scanf("%d%d%d%d", &N, &M, &gun, &ener) != EOF) {
memset(G, 0, sizeof(G));
for(int i = 0; i < gun; ++i) {
scanf(" %c%d%d%d%d", &shot[i].dir,
&shot[i].t, &shot[i].v, &shot[i].i, &shot[i].j);
G[shot[i].i][shot[i].j] = -1;
}
// print();
bfs();
}
return 0;
}