离散化+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 ...
随机推荐
- Python模块:logging、
logging模块: 很多程序都有记录日志的需求,并且日志中包含的信息既有正常的程序访问日志,还可能有错误.警告等信息输出.Python的logging模块提供了标准的日志接口,你可以通过它存储各种格 ...
- 【NOIP2016】天天爱跑步(树上差分)
题意: 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.?天天爱跑步?是一个养成类游戏,需要 玩家每天按时上线,完成打卡任务.这个游戏的地图可以看作一一棵包含 N个结点 ...
- bzoj——3555: [Ctsc2014]企鹅QQ
3555: [Ctsc2014]企鹅QQ Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 2617 Solved: 921[Submit][Statu ...
- 洛谷——P1036 选数
题目描述 已知 n 个整数 x1,x2,…,xn,以及一个整数 k(k<n).从 n 个整数中任选 k 个整数相加,可分别得到一系列的和.例如当 n=4,k=3,4 个整数分别为 3,7,12, ...
- AtCoder Grand Contest 012 B Splatter Painting(记忆化搜索)
题意: 给一个包含N个顶点,M条边,无自环和重边的简单无向图,初始每个点颜色都为0,每条边的长度为1,连接着ai,bi两个节点.经过若干个操作, 每次将与某个点vi距离不超过di的所有点染成某种颜色c ...
- codeforces 762E(cdq分治)
题意: n个电台,每个电台有三个属性xi, ri, fi.分别代表电台的坐标,电台的播报范围,以及播报的频率. 对于一对电台i, j,若min(ri, rj) >= |xi - xj|,那么他们 ...
- Ubuntu 16.04无损分区大小调整工具Gparted
安装: sudo apt-get install gparted 使用: 注意: 这款软件可以调整分区大小,且支持无损,但是对于/根目录的分区无法调整,但是它提供ISO工具,可以启动后进行调整. 下载 ...
- Linux下tmp文件夹的文件自动删除的问题(转)
场景: 近日发现有一台机器tmp文件夹下放置的文件无辜丢失,而且排查发现是自动丢失,并且,只是删除10天之前的文件. 本来以为是哪位写了一个自动执行脚本, find了一下10天前的文件删除了. 结果, ...
- yum install tree 出错primary.sqlite.bz2: [Errno -1] Metadata file does not match checks 解决办法
Loaded plugins: fastestmirrorLoading mirror speeds from cached hostfilehttp://ftp.sjtu.edu.cn/centos ...
- 一步步搭建java信息管理系统00 - 前言
开发前,先上效果图吧 信息管理系统,个人认为,以下几个因素是不可缺少的 多tab 因菜单比较多,右侧的树形一定要考虑,如果菜单还是多,那么顶部就要考虑起来了 以后想到什么,再添加吧. 看到easyui ...