题目传送门

 /*
题意:问一个点到另一个点的最少转向次数。
坐标离散化+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. 洛谷 通天系列 P1760 P1757 P1759

    P1760 通天之汉诺塔 汉诺塔问题.一个高精乘单精解决 ans=2^n-1 /*by SilverN*/ #include<algorithm> #include<iostream ...

  2. CSU - 1333 1333: Funny Car Racing(spfa)

    http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1333 这题多了一个限制条件是每一条路都会规律的开放a时间关闭b时间,车子必须在开放的时候进入,在关 ...

  3. php文件上传判断类型

    上传文件对象在$_FILES['Filedata']对象中,临时路径是tmp_name,判断是上传文件是否为真实图片方法很多,我用的是这个: if( !@getimagesize( $_FILES[' ...

  4. 正则表达式lookahead and lookbehind zero-length assertions

    正则表达式非常好的网站: https://www.regular-expressions.info/lookaround.html ---------------------------------- ...

  5. STL之关联容器的映射底层

    STL的关联容器有set, map, multiset, multimap.用于实现它们的底层容器有划入标准的rb_tree和待增加标准的hashtable. 底层容器rb_tree为上层容器提供了一 ...

  6. js美化压缩工具Mark一下

    jscompress https://www.jscompress.cn/

  7. 在head里的CSS link 竟然粗如今body里了?

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcGVhY2Vfb2Zfc291bA==/font/5a6L5L2T/fontsize/400/fill/I0 ...

  8. Android Api Demos登顶之路(四十五)Loader--&gt;Cursor

    这个demo演示了类载入器的用法.关于类载入器的使用我们在前面的demo中已经介绍过了 在此再小小的复习一下. 类载入器的使用步骤: * 1.获取类载入器的管理者LoaderManager manag ...

  9. Go语言核心之美 3.2-slice切片

    Slice(切片)是长度可变的元素序列(与之相应,上一节中的数组是不可变的),每一个元素都有同样的类型.slice类型写作[]T.T是元素类型.slice和数组写法非常像,差别在于slice没有指定长 ...

  10. C语言之基本算法25—牛顿迭代法求方程近似根

    //牛顿迭代法! /* ============================================================ 题目:用牛顿迭代法求解3*x*x*x-2*x*x-16 ...