离散化+BFS HDOJ 4444 Walk
/*
题意:问一个点到另一个点的最少转向次数。
坐标离散化+BFS:因为数据很大,先对坐标离散化后,三维(有方向的)BFS
关键理解坐标离散化,BFS部分可参考HDOJ_1728
*/
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <map>
#include <cmath>
using namespace std; const int MAXN = * + ;
const int INF = 0x3f3f3f3f;
vector<int> nx, ny;
map<int, int> mx, my;
struct Point
{
int x, y, t, d;
Point (int _x = , int _y = ) {x = _x, y = _y, t = ;}
void read(void)
{
scanf ("%d%d", &x, &y);
nx.push_back (x); ny.push_back (y);
}
void updata(void) {x = mx[x]; y = my[y];}
bool operator < (const Point &r) const {return t > r.t;}
}s, e, p[][];
bool maze[*MAXN][*MAXN];
int dp[MAXN][MAXN][];
bool can[MAXN][MAXN][];
int dx[] = {, , , -};
int dy[] = {, , -, };
int w; int compress(vector<int> &x, map<int, int> &mp)
{
vector<int> xs;
sort (x.begin (), x.end ());
x.erase (unique (x.begin (), x.end ()), x.end ());
for (int i=; i<x.size (); ++i)
{
for (int d=-; d<=; ++d) xs.push_back (x[i] + d);
}
sort (xs.begin (), xs.end ());
xs.erase (unique (xs.begin (), xs.end ()), xs.end ());
for (int i=; i<xs.size (); ++i) mp[x[i]] = find (xs.begin (), xs.end (), x[i]) - xs.begin ();
return xs.size ();
} bool check(Point &a)
{
if ( <= a.x && a.x <= w && <= a.y && a.y <= w && dp[a.x][a.y][a.d] > a.t)
{
dp[a.x][a.y][a.d] = a.t;
return true;
}
return false;
} int BFS(void)
{
memset (dp, INF, sizeof (dp));
priority_queue<Point> Q; s.t = ;
for (s.d=; s.d<; ++s.d)
{
Q.push (s); dp[s.x][s.y][s.d] = ;
} while (!Q.empty ())
{
Point now = Q.top (); Q.pop ();
if (dp[now.x][now.y][now.d] < now.t) continue;
if (now.x == e.x && now.y == e.y) return now.t;
for (int d=-; d<=; ++d)
{
Point to = now;
to.d = (to.d + + d) % ;
if (!can[to.x][to.y][to.d]) continue;
int x = * to.x, y = * to.y;
if (maze[x][y] && maze[x+][y+] &&
((now.d % == && d != ) || (now.d % == && d != -))) continue;
if (maze[x+][y] && maze[x][y+] &&
((now.d % == && d != -) || (now.d % == && d != ))) continue;
if (d != ) to.t++;
to.x += dx[to.d]; to.y += dy[to.d];
if (check (to)) Q.push (to);
}
} return -;
} int main(void) //HDOJ 4444 Walk
{
// freopen ("C.in", "r", stdin); while (true)
{
nx.clear (); ny.clear (); mx.clear (); my.clear ();
s.read (); e.read ();
if (!s.x && !s.y && !e.x && !e.y) break;
memset (maze, false, sizeof (maze)); int n; scanf ("%d", &n);
for (int i=; i<=n; ++i)
{
Point *t = p[i];
t[].read (); t[].read ();
if (t[].x > t[].x) swap (t[], t[]);
if (t[].y > t[].y)
{
Point a = t[], b = t[];
t[].y = b.y; t[].y = a.y;
}
t[] = (Point) {t[].x, t[].y};
t[] = (Point) {t[].x, t[].y};
} w = max (compress (nx, mx), compress (ny, my));
s.updata (); e.updata ();
for (int i=; i<=n; ++i)
{
Point *t = p[i];
for (int j=; j<; ++j) t[j].updata ();
for (int j=; j<; ++j) t[j] = Point (*t[j].x, *t[j].y);
for (int j=t[].x+; j<=t[].x; ++j)
{
for (int k=t[].y+; k<=t[].y; ++k) maze[j][k] = true; //离散化后将矩形涂黑
}
} memset (can, true, sizeof (can));
for (int i=; i<w; ++i)
{
for (int j=; j<w; ++j)
{
int x = i * , y = j * ;
bool *d = can[i][j];
if (maze[x][y+] && maze[x+][y+]) d[] = false; //判断4个方向能不能走
if (maze[x+][y] && maze[x+][y+]) d[] = false;
if (maze[x][y] && maze[x+][y]) d[] = false;
if (maze[x][y] && maze[x][y+]) d[] = false;
}
} printf ("%d\n", BFS ());
} return ;
}
离散化+BFS HDOJ 4444 Walk的更多相关文章
- BFS+贪心 HDOJ 5335 Walk Out
题目传送门 /* 题意:求从(1, 1)走到(n, m)的二进制路径值最小 BFS+贪心:按照标程的作法,首先BFS搜索所有相邻0的位置,直到1出现.接下去从最靠近终点的1开始, 每一次走一步,不走回 ...
- HDU 5925 Coconuts 【离散化+BFS】 (2016CCPC东北地区大学生程序设计竞赛)
Coconuts Time Limit: 9000/4500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Su ...
- hdu 4444 Walk (离散化+建图+bfs+三维判重 好题)
Walk Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Submi ...
- HDU 4444 Walk (离散化建图+BFS+记忆化搜索) 绝对经典
题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4444 题意:给你一些n个矩形,给你一个起点,一个终点,要你求从起点到终点最少需要转多少个弯 题解:因为 ...
- Codeforces243C-Colorado Potato Beetle(离散化+bfs)
Old MacDonald has a farm and a large potato field, (1010 + 1) × (1010 + 1) square meters in size. Th ...
- BFS HDOJ 1728 逃离迷宫
题目传送门 /* BFS:三维BFS,加上方向.用dp[x][y][d]记录当前需要的最少转向数 */ #include <cstdio> #include <algorithm&g ...
- BFS HDOJ 2102 A计划
题目传送门 题意:中文题面 分析:双层BFS,之前写过类似的题.总结坑点: 1.步数小于等于T都是YES 2. 传送门的另一侧还是传送门或者墙都会死 3. 走到传送门也需要一步 #include &l ...
- hdoj 5335 Walk Out
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5335 #include<stdio.h> #include<cstring> ...
- hdu 4400 Mines(离散化+bfs+枚举)
Problem Description Terrorists put some mines in a crowded square recently. The police evacuate all ...
随机推荐
- 安装K/3 Cloud过程中发现的两个新问题。
卸载掉K/3 Cloud然后重装时出现下面的错误提示: 可能原因: 1.安装目录下的Setup.exe会检查操作系统版本.有些操作系统可能是被串改过注册信息,所以取不到版本信息(有些是因为盗版的原因) ...
- [转]如何阅读android framework源码
但如果想深入的了解Android系统, 那么可以看下我的一些简单的总结. 知识 Java Java是AOSP的主要语言之一. 没得说, 必需熟练掌握. 熟练的Android App开发 Linux A ...
- 用JQ实现基础的添加,插入,删除功能。
在eclipse里面运行代码即可,如果您是其他应用,请选择对您有帮助的代码即可,如果有写错或不懂的地方请联系QQ:1633420056,谢谢,祝学习进步 <!DOCTYPE html>&l ...
- 洛谷 P4136 谁能赢呢?
P4136 谁能赢呢? 题目描述 小明和小红经常玩一个博弈游戏.给定一个n×n的棋盘,一个石头被放在棋盘的左上角.他们轮流移动石头.每一回合,选手只能把石头向上,下,左,右四个方向移动一格,并且要求移 ...
- 洛谷 P4057 [Code+#1]晨跑
P4057 [Code+#1]晨跑 题目描述 “无体育,不清华”.“每天锻炼一小时,健康工作五十年,幸福生活一辈子” 在清华,体育运动绝对是同学们生活中不可或缺的一部分.为了响应学校的号召,模范好学生 ...
- spring依赖注入中获取JavaBean
一.这个接口有什么用? 当一个类实现了这个接口(ApplicationContextAware)之后,这个类就可以方便获得ApplicationContext中的所有bean.换句话说,就是这个类可以 ...
- SpringBoot 基于jjwt快速实现token授权
1.添加maven依赖注解 <!--JJWT库--> <dependency> <groupId>io.jsonwebtoken</groupId> & ...
- 比真机还快的Android模拟器——Genymotion
比真机还快的Android模拟器--Genymotion ----转载请注明出处:coder-p ...
- vue组件之间的通信,父子之间的数据通信
父子组件之间的通信问题既可以传递数据也可以传递变量,父组件传递数据给子组件可以使用props,子组件传递数据给父组件则可以自定义函数来监听子组件的事件发射器. 首先说说组件注册,组件的注册分为全局注册 ...
- Linux 内核开发 - 内存管理
1.1什么是内存管理 内存管理是对计算机内存进行分配和使用的技术.内存管理主要存在于多任务的操作系统中,因为内存资源极其有限.须要在不同的任务之间共享内存,内存管理的存在就是要高效.高速的非配内存,并 ...