• 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
    ",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!
    ");
    }
    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;
    }
  • 相关阅读:
    HTML元素事件说明
    JQuery基本方法介绍和使用
    Eclipse设置注释模板
    AJAX回调(调用后台方法返回数据)
    Hibernate常用增删改查方法
    C memset
    PAT-Top1002. Business (35)
    PAT-Top1001. Battle Over Cities
    聂老师的考验(反向bfs)
    CSUST选拔赛题解
  • 原文地址:https://www.cnblogs.com/dashuzhilin/p/4454828.html
Copyright © 2020-2023  润新知