HDU3533 Escape —— BFS / A*算法 + 预处理
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3533
Escape
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1792 Accepted Submission(s): 529
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.
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.
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).
Now, please tell Little A whether he can escape.
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.
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
Bad luck!
题解:
题目要求:
1.直接把能量限制当成时间限制吧,在规定的时间内,从左上角到达右下角。
2.人可以上下左右走或不走, 每座城堡都有一支方向固定的枪,每支枪都有规定的速度和发射频率。
3.人只有在整数时刻下与子弹相遇才会被命中。
4.如果一座城堡被其他子弹射中,那颗子弹会被挡下。注意:即使不是在整数时刻射中,子弹也会被挡下。
做法:
1.开一个三维数组 hav[x][y][time],表明在time时刻, 坐标(x,y)上有无子弹。显然需要预处理这个数组。
2.使用BFS或者A*搜索
3.关于判重:一开始想到,由于子弹的进程是动态的,所以人可能为了回避子弹而往回走,所以就没有加vis判重(当初想到的是vis[x][y]的二维判重)。结果当然是不能通过了,后来看了下题解,开了个三维判重:vis[x][y][time],即增加了"时刻"这一维度。
问:那平常的的为什么开二维判重(vis[x][y])就够了呢,如POJ1077 八数码?
答:因为平常的题目,不用往回走。当第一次被访问的时候,这个位置被访问的最早时间一定是当前时间,之后的访问时间都不可能小于它,这个最早时间对于题目来说是最优 的,所以不用加上“时间”维度。而此题可以往回走,有可能出现最早时刻到达了这个位置,而下一时刻不管怎么走,都会被射死,反而是第二早访问时间才可以逃过一劫。因此这个最早访问时间对于题目来说不一定是最优的,所以此题要加上“时间”维度来判重。
BFS:
Accepted | 3533 | 764MS | 25768K | 2698 B |
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
#define ms(a,b) memset((a),(b),sizeof((a)))
using namespace std;
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int MOD = 1e9+;
const int MAXN = +; bool M[MAXN][MAXN], hav[MAXN][MAXN][];
bool vis[MAXN][MAXN][]; int dir[][] = {-,, ,, ,, ,-, ,};
int n, m, k, d; struct
{
int dir, x, y, t,v;
}ca[MAXN]; struct node
{
int x, y, step;
}; void pre_set()
{
ms(hav, );
for(int i = ; i<k; i++) //枚举城堡
{
for(int j = ; j<=d; j += ca[i].t) //模拟一颗子弹
{
for(int k = ; ; k++) //枚举路程
{
int x = ca[i].x + dir[ca[i].dir][]*k;
int y = ca[i].y + dir[ca[i].dir][]*k;
if(x< || x>n || y< ||y>m || M[x][y]) break;
if(k%ca[i].v==) //到达整点时刻,更新hav数组
hav[x][y][j+k/ca[i].v] = true;
}
}
}
} queue<node>que;
int bfs()
{
ms(vis ,);
while(!que.empty()) que.pop(); node now, tmp;
now.x = now.y = ;
now.step = ;
vis[][][] = true;
que.push(now); while(!que.empty())
{
now = que.front();
que.pop(); if(now.step>d) //累死了
return -;
if(now.x==n && now.y==m) //顺利回营
return now.step; for(int i = ; i<; i++)
{
tmp.x = now.x + dir[i][];
tmp.y = now.y + dir[i][];
tmp.step = now.step + ;
if(tmp.x>= && tmp.x<=n && tmp.y>= && tmp.y<=m && !M[tmp.x][tmp.y]
&& !hav[tmp.x][tmp.y][tmp.step] && !vis[tmp.x][tmp.y][tmp.step])
{
vis[tmp.x][tmp.y][tmp.step] = ;
que.push(tmp);
}
}
}
return -;
} int main()
{
while(scanf("%d%d%d%d",&n,&m,&k,&d)!=EOF)
{
ms(M, );
char dir;
for(int i = ; i<k; i++)
{
getchar();
scanf("%c%d%d%d%d",&dir, &ca[i].t, &ca[i].v, &ca[i].x, &ca[i].y);
if(dir=='N') ca[i].dir = ;
if(dir=='S') ca[i].dir = ;
if(dir=='E') ca[i].dir = ;
if(dir=='W') ca[i].dir = ;
M[ca[i].x][ca[i].y] = ;
} pre_set();
int ans = bfs();
if(ans==-)
puts("Bad luck!");
else
printf("%d\n", ans);
}
}
A*:
Accepted | 3533 | 374MS | 26092K | 2861 B |
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
#define ms(a,b) memset((a),(b),sizeof((a)))
using namespace std;
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int MOD = 1e9+;
const int MAXN = +; bool M[MAXN][MAXN], hav[MAXN][MAXN][];
bool vis[MAXN][MAXN][]; int dir[][] = {-,, ,, ,, ,-, ,};
int n, m, k, d; struct
{
int dir, x, y, t,v;
}ca[MAXN]; struct node
{
int x, y, f, g, h; //g即为step
bool operator<(const node &a)const{
return f>a.f;
}
}; void pre_set()
{
ms(hav, );
for(int i = ; i<k; i++) //枚举城堡
{
for(int j = ; j<=d; j += ca[i].t) //模拟一颗子弹
{
for(int k = ; ; k++) //枚举路程
{
int x = ca[i].x + dir[ca[i].dir][]*k;
int y = ca[i].y + dir[ca[i].dir][]*k;
if(x< || x>n || y< ||y>m || M[x][y]) break;
if(k%ca[i].v==) //到达整点时刻,更新hav数组
hav[x][y][j+k/ca[i].v] = true;
}
}
}
} priority_queue<node>que;
int bfs()
{
ms(vis ,);
while(!que.empty()) que.pop(); node now, tmp;
now.x = now.y = ;
now.g = ;
vis[][][] = true;
que.push(now); while(!que.empty())
{
now = que.top();
que.pop(); if(now.g>d) //累死了
return -;
if(now.x==n && now.y==m) //顺利回营
return now.g; for(int i = ; i<; i++)
{
tmp.x = now.x + dir[i][];
tmp.y = now.y + dir[i][];
tmp.g = now.g + ;
if(tmp.x>= && tmp.x<=n && tmp.y>= && tmp.y<=m && !M[tmp.x][tmp.y]
&& !hav[tmp.x][tmp.y][tmp.g] && !vis[tmp.x][tmp.y][tmp.g])
{
vis[tmp.x][tmp.y][tmp.g] = ;
tmp.h = abs(tmp.x-n) + abs(tmp.y-m);
tmp.f = tmp.g + tmp.h;
que.push(tmp);
}
}
}
return -;
} int main()
{
while(scanf("%d%d%d%d",&n,&m,&k,&d)!=EOF)
{
ms(M, );
char dir;
for(int i = ; i<k; i++)
{
getchar();
scanf("%c%d%d%d%d",&dir, &ca[i].t, &ca[i].v, &ca[i].x, &ca[i].y);
if(dir=='N') ca[i].dir = ;
if(dir=='S') ca[i].dir = ;
if(dir=='E') ca[i].dir = ;
if(dir=='W') ca[i].dir = ;
M[ca[i].x][ca[i].y] = ;
} pre_set();
int ans = bfs();
if(ans==-)
puts("Bad luck!");
else
printf("%d\n", ans);
}
}
HDU3533 Escape —— BFS / A*算法 + 预处理的更多相关文章
- HDU 3533 Escape (BFS + 预处理)
Escape Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total S ...
- poj 3501 Escape from Enemy Territory 预处理+二分+bfs
传送门 给一个起点一个终点, 给出整个地图的宽和高, 给出n个敌人的坐标. 让你找到一条路径, 这条路径上的点距离所有敌人的距离都最短, 输出最短距离. 首先预处理出来地图上的所有点到敌人的最短距离, ...
- 【算法系列学习】[kuangbin带你飞]专题二 搜索进阶 D - Escape (BFS)
Escape 参考:http://blog.csdn.net/libin56842/article/details/41909459 [题意]: 一个人从(0,0)跑到(n,m),只有k点能量,一秒消 ...
- 【搜索】 HDU 3533 Escape BFS 预处理
要从0,0 点 跑到m,n点 路上会有k个堡垒发射子弹.有子弹的地方不能走,子弹打到别的堡垒就会消失,或者一直飞出边界(人不能经过堡垒 能够上下左右或者站着不动 每步都须要消耗能量 一共同拥有en ...
- HDU3533 Escape
题目: The students of the HEU are maneuvering for their military training. The red army and the blue a ...
- BFS/DFS算法介绍与实现(转)
广度优先搜索(Breadth-First-Search)和深度优先搜索(Deep-First-Search)是搜索策略中最经常用到的两种方法,特别常用于图的搜索.其中有很多的算法都用到了这两种思想,比 ...
- 图论——读书笔记(基于BFS广度优先算法的广度优先树)
广度优先树 对于一个图G=(V,E)在跑过BFS算法的过程中会创建一棵广度优先树. 形式化一点的表示该广度 优先树的形成过程是这样的: 对于图G=(V,E)是有向图或是无向图, 和图中的源结点s, 我 ...
- HDU 3533 Escape(bfs)
Escape Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- (原创)BFS广度优先算法,看完这篇就够了
BFS算法 上一篇文章讲解了DFS深度优先遍历的算法,我们说 DFS 顾名思义DEEPTH FIRET,以深度为第一标准来查找,以不撞南墙不回头的态度来发掘每一个点,这个算法思想get到了其实蛮简单. ...
随机推荐
- mysql语句优化方案(网上流传)
关于mysql处理百万级以上的数据时如何提高其查询速度的方法 最近一段时间由于工作需要,开始关注针对Mysql数据库的select查询语句的相关优化方法. 由于在参与的实际项目中发现当mysql表的数 ...
- Linux(15):shell 编程
shell基础 什么是 shell ? Shell是一个命令解释器,它的作用是解释执行用户输入的命令及程序等,用户输入一条命令, Shell 就解释执行一条. 这种从键盘一输入命令,就可以立即得到回应 ...
- 初学Android,BroadcastReceiver之发送接收广播
BroadcastReceiver用于监听系统全局广播消息,由于BroadcastReceiver是一种全局的监听器,因此它可以非常方便地实现系统中不同组件之间通信 启动它需要两步 1.创建需要启动的 ...
- hdu4862 2014多校B题/ 费用流(最优情况下用不大于K条路径覆盖)(不同的解法)
题意: 一个数字矩阵,可以出发K次,每次可以从右边或者下面走,要求(在收益最大情况下)覆盖全图,不能则输出-1.(规则:每次跳一步的时候若格子数字相等则获得该数字的能量,每跳一步消耗距离的能量).每个 ...
- codeforces 1051 F
多源点最短路. 但是有限制,m - n <= 20,边数 - 点数 <= 20, 所以这个图非常的稀疏. 任意提取出一个生成树出来,LCA处理任意两点最短路. 然后再去遍历那些多余出来的点 ...
- HDU - 5572 An Easy Physics Problem (计算几何模板)
[题目概述] On an infinite smooth table, there's a big round fixed cylinder and a little ball whose volum ...
- JQuery select 编程时选中原有的值
js 此为核心代码 $(document).ready(function(){ $("#carTypeId").attr("value",'${carInfo. ...
- iinflux数据库使用
特殊用法: http://blog.fatedier.com/2016/07/05/research-of-time-series-database-influxdb/ 创建表及表中的key和valu ...
- 安装ftp服务器
Linux安装ftp组件 1 安装vsftpd组件 安装完后,有/etc/vsftpd/vsftpd.conf文件,是vsftp的配置文件. [root@bogon ~]# yum -y insta ...
- 基于Android的远程视频监控系统(含源码)
基本过程是android作为socket客户端将采集到的每一帧图像数据发送出去,PC作为服务器接收并显示每一帧图像实现远程监控.图片如下(后来PC端加了个拍照功能)... (PS.刚学android和 ...