一看就是BFS,但是该题不是很好处理。 给的时限很宽裕,所以对于各个炮塔的状态判断其实是可以在BFS里现算的。
我一开始想将各个炮塔在d秒范围内的状态先算出来然后存在数组中,结果MLE,换了个bool型的数组终于勉强存下了。 然后就开始WA,后来才发现原来子弹的途中只要有炮塔就会被阻挡,而不是炮塔被击中时才阻挡子弹。 这样就可以AC了,还有就是HDU的discuss里的数据是错误的,炮塔所在位置也是不能站人的。
细节参见代码:
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
typedef long long ll;
const int INF = 1000000000;
const int maxn = 100 + 1;
const int maxd = 1000 + 1;
int n,m,k,d,ans;
bool vis[maxd][maxn][maxn],t[maxd][maxn][maxn];
bool haha[maxn][maxn];
struct castle{
char dir[1];
int t,v,x,y;
}a[maxn];
struct node{
int t,x,y;
node(int t=0, int x=0, int y=0):t(t),x(x),y(y) {}
bool operator == (const node& rhs) const {
return t == rhs.t && x == rhs.x && y == rhs.y;
}
};
int dx[] = {1,0,-1,0,0};
int dy[] = {0,1,0,-1,0};
queue<node> q;
int BFS() {
while(!q.empty()) q.pop();
vis[0][0][0] = 1;
q.push(node(0,0,0));
node u;
int x,y;
while(!q.empty()) {
u = q.front(); q.pop();
if(u.x == n && u.y == m) return u.t;
if(u.t > d) break;
for(int i=0;i<5;i++) {
x = u.x + dx[i]; y = u.y + dy[i];
if(x < 0 || x > n || y < 0 || y > m ) continue;
if(!t[u.t+1][x][y] && !vis[u.t+1][x][y] && !haha[x][y]) {
vis[u.t+1][x][y] = 1;
q.push(node(u.t+1,x,y));
}
}
}
return -1;
}
int main() {
while(~scanf("%d%d%d%d",&n,&m,&k,&d)) {
memset(vis,false,sizeof(vis));
memset(haha,false,sizeof(haha));
memset(t,false,sizeof(t));
int x,y,tt;
for(int i=1;i<=k;i++) {
scanf("%s%d%d%d%d",a[i].dir,&a[i].t,&a[i].v,&a[i].x,&a[i].y);
haha[a[i].x][a[i].y] = 1; //炮塔所在
}
for(int i=1;i<=k;i++) { //计算各个时间点哪些地方有子弹
if(a[i].dir[0] == 'N') {
for(int j=0;j<=d;j+=a[i].t) {
x = a[i].x; y = a[i].y;
tt = j;
for(int k=x;k>=0;k-=a[i].v) {
t[tt][k][y] = 1;
tt++;
bool ok = false; //被炮塔阻挡/下同
for(int p=(k-a[i].v >= 0 ? k-a[i].v : 0);p<=k-1;p++)
if(haha[p][y]) { ok = true; break; }
if(ok) break;
if(tt > d+1) break;
}
}
}
else if(a[i].dir[0] == 'S') {
for(int j=0;j<=d;j+=a[i].t) {
x = a[i].x; y = a[i].y;
tt = j;
for(int k=x;k<=n;k+=a[i].v) {
t[tt][k][y] = 1;
tt++;
bool ok = false;
for(int p=(k+a[i].v <= n ? k+a[i].v : n); p>=k+1; p--)
if(haha[p][y]) { ok = true; break; }
if(ok) break;
if(tt > d+1) break;
}
}
}
else if(a[i].dir[0] == 'E') {
for(int j=0;j<=d;j+=a[i].t) {
x = a[i].x; y = a[i].y;
tt = j;
for(int k=y;k<=m;k+=a[i].v) {
t[tt][x][k] = 1;
tt++;
bool ok = false;
for(int p=(k+a[i].v <= m ? k+a[i].v : m); p>=k+1; p--)
if(haha[x][p]) { ok = true; break; }
if(ok) break;
if(tt > d+1) break;
}
}
}
else for(int j=0;j<=d;j+=a[i].t) {
x = a[i].x; y = a[i].y;
tt = j;
for(int k=y;k>=0;k-=a[i].v) {
t[tt][x][k] = 1;
tt++;
bool ok = false;
for(int p=(k-a[i].v >= 0 ? k-a[i].v : 0); p<=k-1; p++)
if(haha[x][p]) { ok = true; break; }
if(ok) break;
if(tt > d+1) break;
}
}
}
ans = BFS();
if(ans == -1) printf("Bad luck!\n");
else printf("%d\n",ans);
}
return 0;
}