HDU 3533 Escape(BFS)

45 篇文章 0 订阅
44 篇文章 0 订阅

一看就是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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值