[kuangbin]专题二 搜索进阶 Escape HDU - 3533【BFS】

【题目描述】
The students of the HEU are maneuvering for their military training.
The red army and the blue army are at war today.The blue army finds that Little A is the spy of the red army,so Little A has to escape from the headquarters of the blue army to that of the red army.The battle field is a rectangle of size m*n,and the headquarters of the blue army and the red army are placed at (0, 0) and (m, n), respectively, which means that Little A will go from (0, 0) to (m, n). The picture below denotes the shape of the battle field and the notation of directions that we will use later.
HEU的学生正在进行军事训练。
红军和蓝军今天正在打仗。蓝军发现小A是红军的间谍,所以小A必须从蓝军的司令部逃到红军的总部去,战场是一个m * n大小的矩形,蓝军和红军的总部设在(0,0)和(m,n),这意味着小A将分别从(0,0)到(m,n)。下面的图片表示战场的形状和我们稍后使用的指示符号。
在这里插入图片描述
The blue army is eager to revenge,so it tries its best to kill Little A during his escape.The blue army places many castles,which will shoot to a fixed direction periodically.It costs Little A one unit of energy per second,whether he moves or not.If he uses up all his energy or gets shot at sometime,then he fails.Little A can move north,south,east or west,one unit per second.Note he may stay at times in order not to be shot.
蓝军渴望复仇,所以他们尽可能在小A逃离过程种杀死他,蓝军放置了好几个城堡会朝一个方向周期性地射击。小A每秒消耗一个能量无论他是否移动。如果他耗尽了所有的能量或者被击中,他就失败了。小A可以向北、南、东或西移动,每秒钟一个单位。注意,为了不被枪杀,他有时会停下来。
To simplify the problem,let’s assume that Little A cannot stop in the middle of a second.He will neither get shot nor block the bullet during his move,which means that a bullet can only kill Little A at positions with integer coordinates.Consider the example below.The bullet moves from (0, 3) to (0, 0) at the speed of 3 units per second,and Little A moves from (0, 0) to (0, 1) at the speed of 1 unit per second.Then Little A is not killed. But if the bullet moves 2 units per second in the above example,Little A will be killed at (0, 1).
为了简化这个问题,让我们假设小A不能在一秒内停止。他在移动时既不会被射中,也不会阻挡子弹,这意味着一颗子弹只能在整数坐标的位置杀死小A。考虑下面的例子。子弹以每秒3个单位的速度从(0,3)移动到(0,0),小A以每秒1单位的速度从(0,0)移动到(0,1)。那小A就不会被杀了。但是,在上面的例子中,如果子弹每秒移动两个单位,小A将在(0,1)处被杀死。
Now, please tell Little A whether he can escape.
现在,请告诉小A他能否逃脱。

【输入】
For every test case,the first line has four integers,m,n,k and d (2<=m,n<=100,0<=k<=100,m+n<=d<=1000).m and n are the size of the battle ground,k is the number of castles and d is the units of energy Little A initially has.The next k lines describe the castles each.Each line contains a character c and four integers,t,v,x and y.Here c is ‘N’, ‘S’, ‘E’ or ‘W’ giving the direction to which the castle shoots,t is the period,v is the velocity of the bullets shot (i.e. units passed per second),and (x, y) is the location of the castle.Here we suppose that if a castle is shot by other castles,it will block others’ shots but will NOT be destroyed.And two bullets will pass each other without affecting their directions and velocities.
All castles begin to shoot when Little A starts to escape.
Proceed to the end of file.
对于每个测试样例,第一行有四个整数,m、n、k和d(2<=m,n<=100,0<=k<=100,m+n<=d<=1000)。m和n是战场的大小,k是城堡的数量,d是最初拥有的能量单位。下面的k行描述每个城堡。每一行包含一个字符c和四个整数t、v、x和y。这里c是‘N’,‘S’,‘E’或‘W’,给出了城堡射击的方向, t是周期,v是子弹发射的速度(即每秒通过的单位),(x,y)是城堡的位置。在这里,我们假设,如果一个城堡被其他城堡射击,它将阻止其他人的射击,但不会被摧毁。两颗子弹会在不影响方向和速度的情况下互相穿透。当小A开始逃跑的时候,所有的城堡都开始射击。继续到文件的末尾。

【输出】
If Little A can escape, print the minimum time required in seconds on a single line. Otherwise print “Bad luck!” without quotes.
如果小A可以逃逸,请在一行上以秒为单位打印所需的最短时间。否则就打印“Bad luck!”没有引号。

【样例输入】
4 4 3 10
N 1 1 1 1
W 1 1 3 2
W 2 1 2 4
4 4 3 10
N 1 1 1 1
W 1 1 3 2
W 1 1 2 4

【样例输出】
9
Bad luck!

题目链接:https://cn.vjudge.net/problem/HDU-3533

一个爆内存爆到心态爆炸的故事
BFS,每次往4个方向看是否会被射死,不会就把下一步进队
内存卡的比较紧,判断的过程写成函数调用会爆,vis不写会爆,vis用int写也会爆,数据特别水,样例都过不了的代码交上去试一下还爆不爆内存竟然都能过

AC代码如下:

#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
static const int MAXN=100;
static const int MAXT=1000;
static const int dx[]={0,0,0,1,-1},dy[]={0,1,-1,0,0};
int m,n,k,d;
struct Castle{
    int t,v;
    int kind;
};
struct Node{
    int x,y;
    int step;
};
bool vis[MAXT+10][MAXN+10][MAXN+10];
Castle mp[MAXN+10][MAXN+10];
void bfs(Node node)
{
    queue<Node> Q;
    Q.push(node);
    vis[0][0][0]=true;
    while(!Q.empty())
    {
        Node now=Q.front();
        Q.pop();
        if(now.x==n && now.y==m && now.step<=d)
        {
            cout<<now.step<<endl;
            return;
        }
        if(now.step>d)
        {
            cout<<"Bad luck!"<<endl;
            return;
        }
        for(int i=0;i<=4;i++)
        {
            Node next;
            next.x=now.x+dx[i];
            next.y=now.y+dy[i];
            next.step=now.step+1;
            if(!vis[next.step][next.x][next.y] && 0<=next.x && next.x<=n && 0<=next.y && next.y<=m && !mp[next.x][next.y].kind && next.step<=d)
            {
                bool flag=true;
                for(int i=next.x-1;i>=0;i--)
                {
                    if(mp[i][next.y].kind)
                    {
                        if(mp[i][next.y].kind==2)
                        {
                            if((next.x-i)%mp[i][next.y].v==0 && (next.step-(next.x-i)/mp[i][next.y].v)%mp[i][next.y].t==0)
                            {
                                flag=false;
                                break;
                            }
                        }
                        break;
                    }
                }
                if(!flag)
                    continue;
                for(int i=next.x+1;i<=n;i++)
                {
                    if(mp[i][next.y].kind)
                    {
                        if(mp[i][next.y].kind==1)
                        {
                            if((i-next.x)%mp[i][next.y].v==0 && (next.step-(i-next.x)/mp[i][next.y].v)%mp[i][next.y].t==0)
                            {
                                flag=false;
                                break;
                            }
                        }
                        break;
                    }
                }
                if(!flag)
                    continue;
                for(int i=next.y-1;i>=0;i--)
                {
                    if(mp[next.x][i].kind)
                    {
                        if(mp[next.x][i].kind==3)
                        {
                            if((next.y-i)%mp[next.x][i].v==0 && (next.step-(next.y-i)/mp[next.x][i].v)%mp[next.x][i].t==0)
                            {
                                flag=false;
                                break;
                            }
                        }
                        break;
                    }
                }
                if(!flag)
                    continue;
                for(int i=next.y+1;i<=m;i++)
                {
                    if(mp[next.x][i].kind)
                    {
                        if(mp[next.x][i].kind==4)
                        {
                            if((i-next.y)%mp[next.x][i].v==0 && (next.step-(i-next.y)/mp[next.x][i].v)%mp[next.x][i].t==0)
                            {
                                flag=false;
                                break;
                            }
                        }
                        break;
                    }
                }
                if(!flag)
                    continue;
                vis[next.step][next.x][next.y]=true;
                Q.push(next);
            }
        }
    }
    cout<<"Bad luck!"<<endl;
}
int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0),cout.tie(0);
    while(cin>>n>>m>>k>>d)
    {
        memset(mp,0,sizeof(mp));
        memset(vis,false,sizeof(vis));
        for(int i=1;i<=k;i++)
        {
            char ch;
            int t,v,x,y;
            cin>>ch>>t>>v>>x>>y;
            mp[x][y].t=t;
            mp[x][y].v=v;
            if(ch=='N')
                mp[x][y].kind=1;
            else if(ch=='S')
                mp[x][y].kind=2;
            else if(ch=='E')
                mp[x][y].kind=3;
            else if(ch=='W')
                mp[x][y].kind=4;
        }
        bfs(Node{0,0,0});
    }
    return 0;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值