题目传送门

 /*
题意:问一个点到另一个点的最少转向次数。
坐标离散化+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. 【NOIP2017练习&BZOJ4998】星球联盟(强联通分量,并查集)

    题意: 在遥远的S星系中一共有N个星球,编号为1…N.其中的一些星球决定组成联盟,以方便相互间的交流. 但是,组成联盟的首要条件就是交通条件.初始时,在这N个星球间有M条太空隧道.每条太空隧道连接两个 ...

  2. Max Num

    Problem Description There are some students in a class, Can you help teacher find the highest studen ...

  3. [bzoj2150]部落战争_二分图最小路径覆盖

    部落战争 bzoj-2150 题目大意:题目链接. 注释:略. 想法: 显然是最小路径覆盖,我们知道:二分图最小路径覆盖等于节点总数-最大匹配. 所以我们用匈牙利或者dinic跑出最大匹配,然后用总结 ...

  4. IE插件

    在OA上要直接查看word等公告文件,就必须安装office控件.要安装office控件,需要在IE浏览器中做相应的设置.如何设置呢,下面由小编具体介绍下. 工具/原料   OA IE浏览器 方法/步 ...

  5. dubbo的泛化调用研究

    结论: 泛化调用需要继承一个类,在配置文件里需要明确指出generic=true; 泛化调用在书写provider代码时,变化不大: 泛化调用和普通调用的区别主要在consumer,从‘调用’的表面意 ...

  6. HDU 5074 Hatsune Miku 2014 Asia AnShan Regional Contest dp(水

    简单dp #include <stdio.h> #include <cstring> #include <iostream> #include <map> ...

  7. Oracle Warehouse Builder(OWB) 安装报seeding owbsys错误的解决

    今天在RHEL6.4上安装Oracle Warehouse Builder 11.2时在最后一步报错,打开日志查看有例如以下信息: main.TaskScheduler timer[5]2014052 ...

  8. websphere修改jsp不生效的解决办法

    最近在给客户部署系统后,进行UAT测试的时候,发现一些小问题(是一些jsp文件),改好后,就进行增量发布了,可是后来在页面刷新的时候,怎么都是显示不出来效果,后来就把服务websphere重启后,页面 ...

  9. [mac]WireShark检測不到网卡怎么办?

    wireshark是一个很好用的抓包工具,有windows版本号和mac版本号,在mac下安装wireshark,启动后发现提示"There are no interfaces on whi ...

  10. 容器Vector原理(学习)

    一.概述 数据结构同ArrayList,底层都是数组存储,只不过是线程同步的,也就是其 操作方法都是synchronized