HDU 4444:Walk(思维建图+BFS)***
http://acm.hdu.edu.cn/showproblem.php?pid=4444
题意:给出一个起点一个终点,给出n个矩形的两个对立顶点,问最少需要拐多少次弯可以从起点到达终点,如果不能输出-1.
思路:http://blog.csdn.net/asdfgh0308/article/details/8125832看的是这里的。
因为边界是可以走的,所以不能用点直接来做。
这里用到的就是把一个点拆成一个3*3的方块,中心点就是本身,然后对图进行染色。举个染色的例子:

如果染的是某个颜色的顶点,那么对于那个顶点应当将3*3的方块那样染。
接下来就考虑一种‘L’型拐角的怎么去拐,很多种情况需要去列举。
还有一种就是点的两侧都是被染过的,说明这是一个有两条边界相交的点,因此也是不能走的。
还有注意循环结束的条件不是(SX +SY + EX + EY),因为点可以是负,因这个WA了一个晚上才发现!!!
#include <bits/stdc++.h>
using namespace std;
#define N 1010
#define INF 0x3f3f3f3f
struct node {
int x, y;
} p[N][];
struct P {
int x, y, dir;
P () {}
P (int _x, int _y, int _dir) : x(_x), y(_y), dir(_dir) {};
};
int xx[N], yy[N], x[N], y[N], cx, cy, n, sx, sy, ex, ey;
int mp[N][N], dis[N][N][], dx[] = {, -, , }, dy[] = {, , , -}; // 上下右左
bool vis[N][N][];
void Addpoint(int &x, int &y) {
x *= , y *= ;
cx++; xx[cx] = x;
cx++; xx[cx] = x + ;
cx++; xx[cx] = x - ;
cy++; yy[cy] = y;
cy++; yy[cy] = y + ;
cy++; yy[cy] = y - ;
}
void Find(int &wx, int &wy) {
wx = lower_bound(xx + , xx + + cx, wx) - xx;
wy = lower_bound(yy + , yy + + cy, wy) - yy;
}
void Turn(int x, int y) {
if(mp[x-][y-] && mp[x+][y+] && mp[x+][y-] && mp[x-][y+]) mp[x][y] = -; // 四个角都不行
else if(mp[x+][y+] && mp[x+][y-] && mp[x-][y+]) mp[x][y] = ; // 左下角可以
else if(mp[x+][y-] && mp[x+][y+] && mp[x-][y-]) mp[x][y] = ; // 右下角可以
else if(mp[x-][y-] && mp[x-][y+] && mp[x+][y-]) mp[x][y] = ; // 右上角可以
else if(mp[x-][y-] && mp[x-][y+] && mp[x+][y+]) mp[x][y] = ; // 左上角可以
else if(mp[x+][y-] && mp[x-][y+]) mp[x][y] = ; // 左下角右上角可以
else if(mp[x-][y-] && mp[x+][y+]) mp[x][y] = ; // 左上角右下角可以
if(mp[x-][y] && mp[x+][y]) mp[x][y] = -;
if(mp[x][y-] && mp[x][y+]) mp[x][y] = -;
}
void Build() {
memset(mp, , sizeof(mp));
for(int i = ; i <= n; i++)
for(int j = p[i][].x + ; j <= p[i][].x - ; j++)
for(int k = p[i][].y + ; k <= p[i][].y - ; k++)
mp[j][k] = -;
for(int i = ; i <= cx; i++)
for(int j = ; j <= cy; j++)
if(!mp[i][j]) Turn(i, j);
}
bool Check(int x, int y, int nx, int ny, int pdir, int dir) {
if(nx < || nx > cx || ny < || ny > cy) return false;
if(!mp[x][y]) return true;
if(dir == ) { // 上
if(pdir == && (mp[x][y] == || mp[x][y] == )) return true;
if(pdir == && (mp[x][y] == || mp[x][y] == )) return true;
} else if(dir == ) { // 下
if(pdir == && (mp[x][y] == || mp[x][y] == )) return true;
if(pdir == && (mp[x][y] == || mp[x][y] == )) return true;
} else if(dir == ) {
if(pdir == && (mp[x][y] == || mp[x][y] == )) return true;
if(pdir == && (mp[x][y] == || mp[x][y] == )) return true;
} else {
if(pdir == && (mp[x][y] == || mp[x][y] == )) return true;
if(pdir == && (mp[x][y] == || mp[x][y] == )) return true;
}
return false;
} int BFS() {
memset(vis, , sizeof(vis));
memset(dis, INF, sizeof(dis));
queue<P> que; while(!que.empty()) que.pop();
for(int i = ; i < ; i++) {
que.push(P(sx, sy, i)), dis[sx][sy][i] = , vis[sx][sy][i] = ;
}
int ans = INF;
while(!que.empty()) {
P now = que.front(); que.pop();
int x = now.x, y = now.y, dir = now.dir;
if(x == ex && y == ey) ans = min(ans, dis[x][y][dir]);
vis[x][y][dir] = ;
for(int k = ; k < ; k++) {
int nx = now.x + dx[k], ny = now.y + dy[k], ndir = k;
if(!Check(x, y, nx, ny, dir, ndir)) continue;
int w = ndir == dir ? : ; w += dis[x][y][dir];
if(w < dis[nx][ny][ndir]) {
dis[nx][ny][ndir] = w;
if(!vis[nx][ny][ndir]) vis[nx][ny][ndir] = , que.push(P(nx, ny, ndir));
}
}
}
if(ans == INF) puts("-1");
else printf("%d\n", ans);
// puts("");
}
int main() {
while(scanf("%d%d%d%d", &sx, &sy, &ex, &ey)) { // sx + sy + ex + ey == 0
if(!sx && !sy && !ex && !ey) break;
scanf("%d", &n); cx = cy = ;
for(int i = ; i <= n; i++) {
int x1, x2, y1, y2;
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
Addpoint(x1, y1); Addpoint(x2, y2);
if(x1 > x2) swap(x1, x2);
if(y1 > y2) swap(y1, y2);
p[i][] = (node) { x1, y1 };
p[i][] = (node) { x2, y1 };
p[i][] = (node) { x2, y2 };
p[i][] = (node) { x1, y2 };
}
Addpoint(sx, sy); Addpoint(ex, ey);
int tx = cx, ty = cy;
sort(xx + , xx + + cx); cx = unique(xx + , xx + + cx) - xx - ;
sort(yy + , yy + + cy); cy = unique(yy + , yy + + cy) - yy - ;
for(int i = ; i <= n; i++)
for(int j = ; j < ; j++)
Find(p[i][j].x, p[i][j].y);
Find(sx, sy); Find(ex, ey);
Build();
BFS();
}
return ;
}
HDU 4444:Walk(思维建图+BFS)***的更多相关文章
- HDU 4444 Walk (离散化建图+BFS+记忆化搜索) 绝对经典
题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4444 题意:给你一些n个矩形,给你一个起点,一个终点,要你求从起点到终点最少需要转多少个弯 题解:因为 ...
- BZOJ_3073_[Pa2011]Journeys_线段树优化建图+BFS
BZOJ_3073_[Pa2011]Journeys_线段树优化建图+BFS Description Seter建造了一个很大的星球,他准备建造N个国家和无数双向道路.N个国家很快建造好了,用1..N ...
- hdu 4444 Walk (离散化+建图+bfs+三维判重 好题)
Walk Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Submi ...
- HDU 4370 0 or 1(spfa+思维建图+计算最小环)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4370 题目大意:有一个n*n的矩阵Cij(1<=i,j<=n),要找到矩阵Xij(i< ...
- HDU 4292 Food (建图思维 + 最大流)
(点击此处查看原题) 题目分析 题意:某个餐馆出售f种食物,d种饮料,其中,第i种食物有fi份,第i种饮料有di份:此时有n个人来餐馆吃饭,这n个人必须有一份食物和一份饮料才会留下来吃饭,否则,他将离 ...
- Eliminate the Conflict HDU - 4115(2-sat 建图 hhh)
题意: 石头剪刀布 分别为1.2.3,有n轮,给出了小A这n轮出什么,然后m行,每行三个数a b k,如果k为0 表示小B必须在第a轮和第b轮的策略一样,如果k为1 表示小B在第a轮和第b轮的策略不一 ...
- Codeforces Round #523 (Div. 2) E. Politics(最小费+思维建图)
https://codeforces.com/contest/1061/problem/E 题意 有n个点(<=500),标记第i个点的代价a[i],然后分别在这n个点建两棵树,对于每颗树的每个 ...
- Meeting HDU - 5521 虚点建图
Problem Description Bessie and her friend Elsie decide to have a meeting. However, after Farmer John ...
- 逃生 HDU 4857(反向建图 + 拓扑排序)
逃生 链接 Problem Description 糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排成一行. 现在有n个人,从1标号到n.同时有一些奇怪的约束条件,每个都形如:a必 ...
随机推荐
- Win32 键盘事件 - 击键消息、字符消息、插入符号(光标)
注:以下内容为学习笔记,多数是从书本.资料中得来,只为加深印象,及日后参考.然而本人表达能力较差,写的不好.因非翻译.非转载,只好选原创,但多数乃摘抄,实为惭愧.但若能帮助一二访客,幸甚! 以下内容主 ...
- debian kill 进程等命令
netstat -antup 查看所有进程 譬如Firefox现在僵死,无法相应请求.打开一个终端,输入: pgrep firefox 会返回数值,譬如是7198.现在输入: kill 7198 ...
- jquery 隐私迭代
<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...
- DSP Builder 12.0安装及crack方法
在安装dsp_builder之前请确保已安装所需要的matlab版本 在此之前我已经安装了matlab R2011a,下面安装dsp builder 下面就是破解了,因为12.0的版本刚出,还没有相应 ...
- c#代码安装字体文件
public class FontOperate { [DllImport("kernel32.dll", SetLastError = true)] static extern ...
- 关于git远程分支操作
对于用户来说,git给人提交到本地的机会.我们可以在自己的机器上创建不同的branch,来测试和存放不同的代码. 对于代码管理员而言,git有许多优良的特性.管理着不同的分支,同一套源代码可以出不一样 ...
- 逻辑回归模型(Logistic Regression)及Python实现
逻辑回归模型(Logistic Regression)及Python实现 http://www.cnblogs.com/sumai 1.模型 在分类问题中,比如判断邮件是否为垃圾邮件,判断肿瘤是否为阳 ...
- 转换GMT秒数为日期时间格式-Delphi源码
转换GMT秒数为日期时间格式-Delphi源码.收藏最近在写PE分析工具的时候,需要转换TimeDateStamp字段值为日期时间格式,这是Delphi的源码. //把GMT时间的秒数转换成日期时间格 ...
- 轻量级 Material Design 前端框架 MDUI (纯html,css,与css框架跟react vue不冲突)
MDUI 是一个轻量级的 Material Design 前端框架,对照着 Material Design 文档进行开发,争取 1:1 实现 Material Design 中的组件. 多主题支持 M ...
- 12 寸 Retina MacBook 的大秘密: 可用移动电源充电
苹果新款12寸Retina MacBook虽然只有一个USB-C接口,但这个接口的能力却十分强大.它不仅可以进行数据传输和视频输出,还能接收和输入电源.这也就是说,你可以使用移动电源对其进行充电,如果 ...