【HDU - 3533】Escape(bfs)

Escape

 Descriptions:

一个人从(0,0)跑到(n,m),只有k点能量,一秒消耗一点,在图中有k个炮塔,给出炮塔的射击方向c,射击间隔t,子弹速度v,坐标x,y
问这个人能不能安全到达终点
要求: 
1.人不能到达炮塔所在的坐标
2.炮塔会挡住子弹
3.途中遇到子弹是安全的,但是人如果停在这个坐标,而子弹也刚好到这个坐标,人就被射死
4.人可以选择停止不动

Input

对于每个测试用例,第一行有四个整数,m、n、k和d (2<=m, n<=100, 0<=k<=100, m+ n<=d<=1000)。m和n是战场的大小,k是城堡的数量,d是A最初拥有的能量单位。接下来的k行分别描述了这些城堡。每一行包含一个字符c和四个整数,t, v, x和y。c是“N”,“S”,“E”或“W”给城堡的发射方向,t, v是子弹的速度(即单位通过每秒),和(x, y)是城堡的位置。这里我们假设,如果一座城堡被其他城堡击中,它会挡住其他人的射击,但不会被摧毁。两颗子弹会在不影响它们的方向和速度的情况下擦肩而过。

当小A开始逃跑时,所有的城堡都开始射击。

继续到文件末尾。


Output

如果小A能逃跑,在一行中输入其所需的最小秒数。否则,在一行中输出"Bad luck!"(无需带引号)


Sample Input

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

Sample Output

9
Bad luck!

题目链接

https://vjudge.net/problem/HDU-3533

其实不难,我们只需要看当人位于某个点的时候,其四个方向是否有炮塔,这个炮塔是都向人的方向射击,然后再看子弹是否刚好位于这个坐标即可。

而标记的话,vis[x][y][time],对于time时刻,人位于x,y的情况只需要访问一次,这是唯一的

AC代码

#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#define Mod 1000000007
#define eps 1e-6
#define ll long long
#define INF 0x3f3f3f3f
#define MEM(x,y) memset(x,y,sizeof(x))
#define Maxn 105
using namespace std;
int n,m,k,life;
int dt[5][2] = {0,1,1,0,0,-1,-1,0,0,0};//四个方向与停止不动的走法
int map[105][105];
bool vis[105][105][1005];

struct period
{
    char c;
    int t,v;
} s[105][105];

struct node
{
    int x,y,step;
};

int check(int x,int y)
{
    if(x<0 || x>n || y<0 || y>m)
        return 1;
    return 0;
}

void bfs()
{
    node now,net;
    queue<node> q;
    int i,j,flag,dis,timee;
    now.x = now.y = now.step = 0;
    q.push(now);
    vis[0][0][0] = true;
    while(!q.empty())
    {
        now = q.front();
        q.pop();
        if(now.step>life)
            break;
        if(now.x == n && now.y == m)
        {
            cout<<now.step<<endl;
            return ;
        }
        for(i = 0; i<5; i++)
        {
            net = now;
            net.x+=dt[i][0];
            net.y+=dt[i][1];
            net.step++;
            if(check(net.x,net.y))
                continue;
            if(!s[net.x][net.y].t && !vis[net.x][net.y][net.step] && net.step<=life)//在符合条件的情况下,枚举四个方向
            {
                flag = 1;
                for(j = net.x-1; j>=0; j--)//当位于这点,我们往北向寻找是否有朝南方向射击的炮台
                {
                    if(s[j][net.y].t && s[j][net.y].c == ‘S‘)//找到第一个炮台,且这个炮台是朝南射击的
                    {
                        dis = net.x-j;//看炮台与人的距离
                        if(dis%s[j][net.y].v)
                            break;//因为不需要看子弹中途的点,子弹每一秒跑v,距离是dis,dis不能整除v的话,那么子弹是不可能停在这个点的
                        timee = net.step-dis/s[j][net.y].v;//人走的时间减去第一个子弹飞行到这个位置所需的时间
                        if(timee<0)
                            break;//为负数就是第一个子弹都没有经过这个点,那么人绝对安全
                        if(timee%s[j][net.y].t==0)//看间隔,能整除,那么就是后续有子弹刚好到这个点,人死定了
                        {
                            flag = 0;
                            break;
                        }
                    }
                    if(s[j][net.y].t)//找到炮台但不是朝南射击,那么这个炮台会当下后面所有子弹,所以北方向安全我们不需要再找
                        break;
                }
                if(!flag)//这个方向都死定了,后面也就不需要看了
                    continue;
                //其他方向也是一样的道理,就不注释了
                for(j = net.x+1; j<=n; j++)
                {
                    if(s[j][net.y].t && s[j][net.y].c == ‘N‘)
                    {
                        dis = j-net.x;
                        if(dis%s[j][net.y].v)
                            break;
                        timee = net.step-dis/s[j][net.y].v;
                        if(timee<0)
                            break;
                        if(timee%s[j][net.y].t==0)
                        {
                            flag = 0;
                            break;
                        }
                    }
                    if(s[j][net.y].t)
                        break;
                }
                if(!flag)
                    continue;
                for(j = net.y-1; j>=0; j--)
                {
                    if(s[net.x][j].t && s[net.x][j].c == ‘E‘)
                    {
                        dis = net.y-j;
                        if(dis%s[net.x][j].v)
                            break;
                        timee = net.step-dis/s[net.x][j].v;
                        if(timee<0)
                            break;
                        if(timee%s[net.x][j].t==0)
                        {
                            flag = 0;
                            break;
                        }
                    }
                    if(s[net.x][j].t)
                        break;
                }
                if(!flag)
                    continue;
                for(j = net.y+1; j<=m; j++)
                {
                    if(s[net.x][j].t && s[net.x][j].c == ‘W‘)
                    {
                        dis = j-net.y;
                        if(dis%s[net.x][j].v)
                            break;
                        timee = net.step-dis/s[net.x][j].v;
                        if(timee<0)
                            break;
                        if(timee%s[net.x][j].t==0)
                        {
                            flag = 0;
                            break;
                        }
                    }
                    if(s[net.x][j].t)
                        break;
                }
                if(!flag)
                    continue;
                vis[net.x][net.y][net.step] = true;
                q.push(net);
            }
        }
    }
    cout<<"Bad luck!"<<endl;
}

int main()
{
    while(cin>>n>>m>>k>>life)
    {
        MEM(vis,0);
        MEM(s,0);
        for(int i=0; i<k; i++)
        {
            char c;
            int t,v,x,y;
            cin>>c>>t>>v>>x>>y;
            s[x][y].c=c;
            s[x][y].t=t;
            s[x][y].v=v;
        }
        bfs();
    }
    return 0;
}

原文地址:https://www.cnblogs.com/sky-stars/p/11218976.html

时间: 2024-08-09 07:19:00

【HDU - 3533】Escape(bfs)的相关文章

【Aizu - 0558】Cheese(bfs)

-->Cheese 原文是日语,这里就写中文了 Descriptions: 在H * W的地图上有N个奶酪工厂,每个工厂分别生产硬度为1-N的奶酪.有一只老鼠准备从出发点吃遍每一个工厂的奶酪.老鼠有一个体力值,初始时为1,每吃一个工厂的奶酪体力值增加1(每个工厂只能吃一次),且老鼠只能吃硬度不大于当前体力值的奶酪. 老鼠从当前格到上下左右相邻的无障碍物的格需要时间1单位,有障碍物的格不能走.走到工厂上时即可吃到该工厂的奶酪,吃奶酪时间不计.问吃遍所有奶酪最少用时 input 第一行三个整数H(1

【HDU 5750】Dertouzos(数学)

题目给定n和d,都是10的9次方以内,求1到n里面有几个数最大因数是d?1000000组数据.解:求出d的满足p[i]*d<n的最小质因数是第几个质数.即为答案. #include<cstdio> #define N 100002 int t,n,d,pr[N],p[N],num; int main(){ for(int i=2;i<N;i++)if(!pr[i]){ for(int j=i+i;j<N;j+=i) pr[j]=1; p[++num]=i; } scanf(&

【HDU 5811】Colosseo(拓扑+输入优化)

[HDU 5811]Colosseo(拓扑+输入优化) Colosseo Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 446    Accepted Submission(s): 98 Problem Description Mr. Chopsticks keeps N monsters, numbered from 1 to N.

【HDU 5721】Palace(平面最近点对)

[HDU 5721]Palace(平面最近点对) Palace Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 404    Accepted Submission(s): 104 Problem Description The last trial Venus imposes on Psyche is a quest to the

hdu 1728 逃离迷宫 (BFS)

逃离迷宫 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 14376    Accepted Submission(s): 3458 Problem Description 给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,gloria可以穿越,有些地方

【Hibernate学习】 ——ORM(三)

前面几种关系我们以前就经常用,对于继承我们也并不陌生,经常接触的类与类之间的继承用extends关键字,那么在表与表的关系中如何表示呢?下面我们来讲继承映射. 继承有三种实现的策略,单表继承,具体表继承,类表继承.下面来分析一下这三种方式 继承关联类关系  单表继承 每棵类继承树使用一个表,可知,这三个类在一张表中.如下表: 这张表包括了父类,子类的所有属性,通过Type来区分是哪个子类. 对象模型映射到关系模型: <classname="com.bjpowernode.hibernat.

【Hibernate学习】 ——ORM(一)

Hibernate是一种能实现ORM的框架.ORM即Object Relational Mapping,对象关系映射.也就是将关系数据库中表的数据映射成为对象,也就是说将表与表之间的操作映射成对象与对象之间的操作,通过实体类来达到操作表的目的.总之就是把对数据库的操作转化为对对象的操作,从而更体现了面向对象的思想. 一对一关联映射策略包括主键关联和唯一外键关联. 单向一对一 主键关联 让两个对象有相同的主键值,表名它们之间的一对一关系,数据库没有额外的字段来维护它们之间的关系,仅仅通过表的主键来

【Hibernate学习】 ——ORM(二)

上篇博客主要介绍了一对一的关系,主要理解单向与双向的区别,主键关联与唯一外键关联的区别.下面继续介绍一对多与多对多关联. 一对多关联映射 一个班级对应多个学生 单向一对多关系 关系表: classes代码 <classname="com.bjpowernode.hibernat.Classes"table="t_classes"> <idname="id"> <generatorclass="native&

HDU 1728 逃离迷宫(BFS)

Problem Description 给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,gloria可以穿越,有些地方是障碍,她必须绕行,从迷宫的一个位置,只能走到与它相邻的4个位置中,当然在行走过程中,gloria不能走到迷宫外面去.令人头痛的是,gloria是个没什么方向感的人,因此,她在行走过程中,不能转太多弯了,否则她会晕倒的.我们假定给定的两个位置都是空地,初始时,gloria所面向的方向未定,她可