题目传送门

 /*
题意:问一个点到另一个点的最少转向次数。
坐标离散化+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的更多相关文章

  1. BFS+贪心 HDOJ 5335 Walk Out

    题目传送门 /* 题意:求从(1, 1)走到(n, m)的二进制路径值最小 BFS+贪心:按照标程的作法,首先BFS搜索所有相邻0的位置,直到1出现.接下去从最靠近终点的1开始, 每一次走一步,不走回 ...

  2. HDU 5925 Coconuts 【离散化+BFS】 (2016CCPC东北地区大学生程序设计竞赛)

    Coconuts Time Limit: 9000/4500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Su ...

  3. hdu 4444 Walk (离散化+建图+bfs+三维判重 好题)

    Walk Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submi ...

  4. HDU 4444 Walk (离散化建图+BFS+记忆化搜索) 绝对经典

    题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4444 题意:给你一些n个矩形,给你一个起点,一个终点,要你求从起点到终点最少需要转多少个弯 题解:因为 ...

  5. Codeforces243C-Colorado Potato Beetle(离散化+bfs)

    Old MacDonald has a farm and a large potato field, (1010 + 1) × (1010 + 1) square meters in size. Th ...

  6. BFS HDOJ 1728 逃离迷宫

    题目传送门 /* BFS:三维BFS,加上方向.用dp[x][y][d]记录当前需要的最少转向数 */ #include <cstdio> #include <algorithm&g ...

  7. BFS HDOJ 2102 A计划

    题目传送门 题意:中文题面 分析:双层BFS,之前写过类似的题.总结坑点: 1.步数小于等于T都是YES 2. 传送门的另一侧还是传送门或者墙都会死 3. 走到传送门也需要一步 #include &l ...

  8. hdoj 5335 Walk Out

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5335 #include<stdio.h> #include<cstring> ...

  9. hdu 4400 Mines(离散化+bfs+枚举)

    Problem Description Terrorists put some mines in a crowded square recently. The police evacuate all ...

随机推荐

  1. Thinkphp5.0 的使用模型Model更新数据

    Thinkphp5.0 的使用模型Model更新数据 (1)使用update()方法进行更新数据 一.where条件写在更新数据中 (这种情况更新的数据,必须含主键) $res = User::upd ...

  2. Uva -1515 Pool construction(最小割)

    输入一个字符矩阵,'.'代表洞,'#'代表草地.可以把草改成洞花费为d,或者把洞改成草花费为f,最后还要在草和洞之间修围栏花费为b. 首先把最外一圈的洞变成草,并累加花费. 增加一个源点和一个汇点,源 ...

  3. Codeforces 631A Interview【模拟水题】

    题意: 模拟模拟~~ 代码: #include<iostream> using namespace std; const int maxn = 1005; int a[maxn], b[m ...

  4. HDU.P1100 Trees Made to Order 解题报告

    http://www.cnblogs.com/keam37/p/3637717.html  keam所有 转载请注明出处 Problem Description We can number binar ...

  5. openstack setup demo Overview

    Overview openstack是一套开源的云计算部署平台,通过一系列service提供IAAS.每一个service都提供API.具体的service列表如下: dashboard Horizo ...

  6. crontab not running

    there are mutliple ways to describle this issue 1. crontab not running 2. crontab not running and no ...

  7. anaconda是个啥?

    Anaconda具有跨平台(win/mac/linux).包管理(类似于pip).环境管理(类似于virtualenv)的特点,因此很适合快速在新的机器上部署Python环境 Anaconda利用工具 ...

  8. ArcGIS 教程:Workflow Manager 高速浏览

    应用程序概述 Workflow Manager 用户界面提供了用于在整个作业的生命周期中创建和管理作业的工具. 下面全部信息将会在本帮助文档的兴许章节中进行具体的说明. 文件菜单 新建 - 在系统中创 ...

  9. 云计算VDI相关职位招聘

    中电科华云信息技术有限公司是中国优秀的云计算方案提供商和服务商之中的一个.公司依托中国电子科技集团公司,实施"自主.可信.定制.服务"的差异化发展战略,以实现自主创新的技术研发.自 ...

  10. MySQL Study之--MySQL压力測试工具mysqlslap

    MySQL Study之--MySQL压力測试工具mysqlslap 一.Mysqlslap介绍     mysqlslap是MySQL5.1之后自带的benchmark基准測试工具,类似Apache ...