HDU 3533 Escape

题意:一个m*n的矩阵,k个炮台,人物要在d个单位时间内从(0,0)走到(m,n),并给出每架炮台的发射方向、发射时间间隔、炮弹速度、坐标,求人物到达终点的最短时间;

思路:bfs,每走一步都判断一下四个方向是否有危险以确定是否能走这一步,并且不能走到炮台上!!!考虑要周全,vis用bool写,否则超内存;感觉搜索蛮锻炼代码能力的;

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
bool vis[105][105][1005];//改为int就会超内存
int dir[5][2]={{-1,0},{0,1},{1,0},{0,-1},{0,0}};
int m,n,k,d;
int judge(int a,int b)//是否在地图内
{
    if(a<0||a>m||b<0||b>n) return 0;
    return 1;
}
struct node
{
    int x,y,t;
};//人物
struct Node
{
    int v,t;
    char s;
}shot[105][105];//炮台
void bfs()
{
    int flag,dis,temp,i,j;
    node cur,now;
    memset(vis,false,sizeof(vis));
    queue<node> q;
    node s;
    s.x=s.y=s.t=0;
    q.push(s);
    vis[0][0][0]=true;
    while(!q.empty())
    {
        cur=q.front();
        q.pop();
        if(cur.t>d) break;
        if(cur.x==m&&cur.y==n)//到达终点,记得写在for的外面!
        {
              printf("%d\n",cur.t);
              return;
        }
        for(i=0;i<5;i++)
        {
            now.x=cur.x+dir[i][0];
            now.y=cur.y+dir[i][1];
            now.t=cur.t+1;
            if(!judge(now.x,now.y)||vis[now.x][now.y][now.t]||now.t>d) continue;
            if(shot[now.x][now.y].t) continue;//不能走到炮台上,这个判定非常重要,导致花了一个晚上找这个bug
            flag=1;
            for(j=now.x-1;j>=0;j--)
            {
                if(shot[j][now.y].t&&shot[j][now.y].s=='S')//当前位置北边是否有向南射的炮
                {
                    dis=now.x-j;
                    if(dis%shot[j][now.y].v) break;
                    temp=now.t-dis/shot[j][now.y].v;
                    if(temp<0) break;//人物到达该位置是不曾有炮经过
                    if(temp%shot[j][now.y].t==0)//人物被击中
                    {
                        flag=0;break;
                    }
                }
                if(shot[j][now.y].t) break;//若有炮台挡住,则人物北边无危险
            }
            if(!flag) continue;//当前位置危险,不能走
            for(j=now.x+1;j<=m;j++)
            {
                if(shot[j][now.y].t&&shot[j][now.y].s=='N')//检测南边
                {
                    dis=j-now.x;
                    if(dis%shot[j][now.y].v) break;
                    temp=now.t-dis/shot[j][now.y].v;
                    if(temp<0) break;
                    if(temp%shot[j][now.y].t==0)
                    {
                        flag=0;break;
                    }
                }
                if(shot[j][now.y].t) break;
            }
            if(!flag) continue;
            for(j=now.y-1;j>=0;j--)
            {
                if(shot[now.x][j].t&&shot[now.x][j].s=='E')//检测西边
                {
                    dis=now.y-j;
                    if(dis%shot[now.x][j].v) break;
                    temp=now.t-dis/shot[now.x][j].v;
                    if(temp<0) break;
                    if(temp%shot[now.x][j].t==0)
                    {
                        flag=0;
                        break;
                    }
                }
                if(shot[now.x][j].t) break;
            }
            if(!flag) continue;
            for(j=now.y+1;j<=n;j++)
            {
                if(shot[now.x][j].t&&shot[now.x][j].s=='W')//检测东边
                {
                    dis=j-now.y;
                    if(dis%shot[now.x][j].v) break;
                    temp=now.t-dis/shot[now.x][j].v;
                    if(temp<0) break;
                    if(temp%shot[now.x][j].t==0)
                    {
                        flag=0;
                        break;
                    }
                }
                if(shot[now.x][j].t) break;
            }
            if(!flag) continue;
            vis[now.x][now.y][now.t]=true;
            q.push(now);
        }
    }
    printf("Bad luck!\n");
}
int main()
{
    int i,j,v,t,x,y;
    char s;
    while(scanf("%d%d%d%d",&m,&n,&k,&d)!=EOF)
    {
        memset(shot,0,sizeof(shot));
        for(i=0;i<k;i++)
        {
            scanf(" %c %d%d%d%d",&s,&t,&v,&x,&y);//所有炮台信息
            shot[x][y].s=s;
            shot[x][y].t=t;
            shot[x][y].v=v;
        }
        bfs();
    }
    return 0;
}

 

posted on 2015-04-24 22:33  大树置林  阅读(148)  评论(0编辑  收藏  举报

导航