BFS(判断状态) HDOJ 3533 Escape

题目传送门

题意:一个人从(0, 0)逃往(n, m),地图上有朝某个方向开炮的炮台,问最少逃脱步数

分析:主要在状态是否OK,当t时刻走到(x,y),炮台是否刚好打中,因为只能是整数,所以用整除判断。题意不清楚,有些坑点。

#include <bits/stdc++.h>
using namespace std;

const int N = 1e2 + 5;
struct Point	{
	int dir, t, v;		//N 1 E 2 S 3 W 4
}p[N][N];
struct Node	{
	int x, y, step;
	Node() {}
	Node(int x, int y, int step) : x (x), y (y), step (step) {}
};
int dx[5] = {-1, 1, 0, 0, 0};
int dy[5] = {0, 0, -1, 1, 0};
bool vis[N][N][N*10];
int n, m, k, d;

bool check(int x, int y, int tim)	{
	if (x < 0 || x > n || y < 0 || y > m || vis[x][y][tim] || p[x][y].dir != 0)	return false;
	else	return true;
}

bool check2(int x, int y, int tim)	{
	for (int i=x-1; i>=0; --i)	{		//up
		if (p[i][y].v == 0)	continue;
		if (p[i][y].dir != 3)	break;
		int dis = x - i;
		if (dis % p[i][y].v != 0)	break;
		int t = tim - dis / p[i][y].v;
		if (t % p[i][y].t == 0)	return false;
		else	break;
	}
	for (int i=x+1; i<=n; ++i)	{		//down
		if (p[i][y].v == 0)	continue;
		if (p[i][y].dir != 1)	break;
		int dis = i - x;
		if (dis % p[i][y].v != 0)	break;
		int t = tim - dis / p[i][y].v;
		if (t % p[i][y].t == 0)	return false;
		else	break;
	}
	for (int i=y-1; i>=0; --i)	{		//left
		if (p[x][i].v == 0)	continue;
		if (p[x][i].dir != 2)	break;
		int dis = y - i;
		if (dis % p[x][i].v != 0)	break;
		int t = tim - dis / p[x][i].v;
		if (t % p[x][i].t == 0)	return false;
		else	break;
	}
	for (int i=y+1; i<=m; ++i)	{		//right
		if (p[x][i].v == 0)	continue;
		if (p[x][i].dir != 4)	break;
		int dis = i - y;
		if (dis % p[x][i].v != 0)	break;
		int t = tim - dis / p[x][i].v;
		if (t % p[x][i].t == 0)	return false;
		else	break;
	}

	return true;
}

int BFS(void)	{
	Node s;
	s.x = s.y = s.step = 0;
	queue<Node> que;	que.push (s);
	vis[s.x][s.y][0] = true;
	while (!que.empty ())	{
		Node u = que.front ();	que.pop ();
		if (u.step > d)	continue;
		if (u.x == n && u.y == m && u.step <= d)	{
			return u.step;
		}
		for (int i=0; i<5; ++i)	{
			int tx = u.x + dx[i], ty = u.y + dy[i], tsp = u.step + 1;
			if (!check (tx, ty, tsp))	continue;
			if (!check2 (tx, ty, tsp))	continue;
			vis[tx][ty][tsp] = true;
			que.push (Node (tx, ty, tsp));
		}
	}

	return -1;
}

int main(void)	{
	map<char, int> mp;
	mp[‘N‘] = 1;	mp[‘E‘] = 2;	mp[‘S‘] = 3;	mp[‘W‘] = 4;
	while (scanf ("%d%d%d%d", &n, &m, &k, &d) == 4)	{
		memset (vis, false, sizeof (vis));
		memset (p, 0, sizeof (p));
		char str[3];	int t, v, x, y;
		getchar ();
		for (int i=0; i<k; ++i)	{
			scanf ("%s%d%d%d%d", &str, &t, &v, &x, &y);
			p[x][y].dir = mp[str[0]];
			p[x][y].t = t;	p[x][y].v = v;
		}
		int ans = BFS ();
		if (ans == -1)	puts ("Bad luck!");
		else printf ("%d\n", ans);
	}

	return 0;
}

  

时间: 2024-10-29 19:09:28

BFS(判断状态) HDOJ 3533 Escape的相关文章

hdoj 3605 Escape 【中等最大流 | 二分图多重匹配】

题目:hdoj 3605 Escape 分类:中等最大流 | 二分图多重匹配 题意:给出n个人和m个星球,每个人有想去的兴趣,然后每个星球有容量,问能不能让所有人都住在自己想去的星球? 分析:最大流的话卡的非常严,这个题目写了之后手写MTL,超内存,然后加入状态压缩之后TEL,后面没办法了看别人说C++提交能过,改C++Compilation Error,不容易呀,原来C++用的vc编译器,果然改了之后600ms过了. 首先题意很明显,建图方法也很明显,要设一个超级远点s和汇点t,其他的不说了.

BFS判断是否是二分图Bipartite算法

二分图bipartite 使用BFS广度优先判断一个图是否是二分图.基本图操作. 参考 http://www.geeksforgeeks.org/bipartite-graph/ #pragma once #include <stdio.h> #include <iostream> #include <queue> using namespace std; class CheckwhetheragivengraphisBipartiteornot { const sta

HDU 3533 Escape(BFS+预处理)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3533 题目大意:给你一张n* m的地图,人在起点在(0,0)要到达终点(n,m)有k(k<=100)座炮台,每座炮台都有各自的发射方向.发射周期和发射速度,每隔一段时间会发射一定速度的炮弹,人每秒可以选择停在原地或者往上下左右走,问是否能在时间d之内安全到达终点.如果可以,请输出最短时间. 解题思路:BFS+预处理,分为以下几点: ①预处理,用step[x][y][t]记录(x,y)在时间t是否被炮

HDU 3533 Escape (BFS + 预处理)

Escape Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 541    Accepted Submission(s): 141 Problem Description The students of the HEU are maneuvering for their military training. The red army

HDU 3533 Escape BFS搜索

题意:懒得说了 分析:开个no[100][100][1000]的bool类型的数组就行了,没啥可说的 #include <iostream> #include <cstdio> #include <vector> #include <cstring> #include <algorithm> #include <string> #include <cmath> #include <queue> #include

【搜索】 HDU 3533 Escape BFS 预处理

要从0,0 点 跑到m,n点  路上会有k个堡垒发射子弹,有子弹的地方不能走,子弹打到别的堡垒就会消失,或者一直飞出边界(人不能经过堡垒 可以上下左右或者站着不动 每步都需要消耗能量  一共有eng个能量 先预处理出地图 用三维数组表示mp[x][y][time] time表示该时间的地图上储存不能走的点 然后就是普通BFS #include <stdio.h> #include <string.h> #include <stdlib.h> #include <s

hdu5025Saving Tang Monk(bfs+优先队列+状态压缩)

题目链接: huangjing 题意: 给了一幅图,然后这幅图里面有一个孙悟空,一个唐神,然后还有m把钥匙,还有最多5条蛇,然后蛇只要第一次杀死,杀这条蛇的时间为1S,并且后来再遇到的时候就不用加时间了,求最小的拯救时间. 思路: 首先那5条蛇可以用5位二进制数表示,然后开一个3维的数组判重,前两维保存坐标,后一维保存钥匙的状态,那么就可以了,还要注意的是因为有杀蛇这个操作,所以用优先队列来维护每一次搜索的都是最小的步数..那么这个问题就解决了,我开始wa到死,就是在判断是否是蛇的时候,我判断如

BFS+二进制状态压缩 hdu-1429

好久没写搜索题了,就当练手吧. vis[][][1025]第三个维度用来维护不同key持有状态的访问情况. 对于只有钥匙没有对应门的位置,置为'.',避免不必要的状态分支. // // main.cpp // hdu_1429 // // Created by Luke on 16/10/8. // Copyright © 2016年 Luke. All rights reserved. // #include <iostream> #include <string> #inclu

[HDOJ5094] Maze (记忆化搜索,BFS,状态压缩)

题目链接:https://vjudge.net/problem/HDU-5094 题意:很典型的迷宫寻路,但是点与点之间有障碍或者门,每个点有钥匙.与其他题不同的地方是障碍不是单纯的某一个点不可以走,而是两点之间.求从一点出发到另一点最短路. 很简单,用G[][][][]存两个点之间的障碍(图大了其实也可以用unordered_map<pii,pii>).钥匙顶多10把,用位压记录钥匙状态,bfs的时候队内节点维护当前点.钥匙拥有情况.最短路.直接记忆化搞就是了. 1 #include <