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)***的更多相关文章

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

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

  2. BZOJ_3073_[Pa2011]Journeys_线段树优化建图+BFS

    BZOJ_3073_[Pa2011]Journeys_线段树优化建图+BFS Description Seter建造了一个很大的星球,他准备建造N个国家和无数双向道路.N个国家很快建造好了,用1..N ...

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

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

  4. HDU 4370 0 or 1(spfa+思维建图+计算最小环)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4370 题目大意:有一个n*n的矩阵Cij(1<=i,j<=n),要找到矩阵Xij(i< ...

  5. HDU 4292 Food (建图思维 + 最大流)

    (点击此处查看原题) 题目分析 题意:某个餐馆出售f种食物,d种饮料,其中,第i种食物有fi份,第i种饮料有di份:此时有n个人来餐馆吃饭,这n个人必须有一份食物和一份饮料才会留下来吃饭,否则,他将离 ...

  6. 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轮的策略不一 ...

  7. Codeforces Round #523 (Div. 2) E. Politics(最小费+思维建图)

    https://codeforces.com/contest/1061/problem/E 题意 有n个点(<=500),标记第i个点的代价a[i],然后分别在这n个点建两棵树,对于每颗树的每个 ...

  8. Meeting HDU - 5521 虚点建图

    Problem Description Bessie and her friend Elsie decide to have a meeting. However, after Farmer John ...

  9. 逃生 HDU 4857(反向建图 + 拓扑排序)

    逃生 链接 Problem Description 糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排成一行. 现在有n个人,从1标号到n.同时有一些奇怪的约束条件,每个都形如:a必 ...

随机推荐

  1. Nginx支持LInux的软链接或硬链接

    在我们配置nginx的时候,有些时候,大部分都是讲root指向真实的目录.但是有些时候,我们需要指向一个软链接.但是配置的时候,发现会有问题. 我们可以通过以下的方法,来解决,让nginx支持软链接/ ...

  2. Form submit

    方法1:使用form onsubmit标签 return XXX()方法 <!--onsubmit--> <form id="formid" name=" ...

  3. WPF编游戏系列 之七 动画效果(2)

    原文:WPF编游戏系列 之七 动画效果(2)        上一篇已经对关闭窗口图标进行了动画效果处理,本篇将对窗口界面的显示和关闭效果进行处理.由于所有的动画效果都是针对窗口界面的Canvas,所以 ...

  4. 【推荐网站】下载国外网盘+强大的离线下载站—offcloud.com

    博主在网上浏览时看到一篇帖子,推荐了一个离线下载网站–offcloud.com,支持上传种子文件.磁力链和几十家网盘的直连下载,厉害了我的哥,这是个啥网站这么666.即使之前咱们写了几篇文章来自建下载 ...

  5. Introduction To The Smart Client Software Factory (CAB/SCSF Part 18)

    1. Shell This is the start-up project for the solution. It is very similar to the start-up projects ...

  6. JAVASCRIPT高程笔记-------第五章 引用类型

    一.Object类型 1.1创建方式 ①new关键字 : var person = new Oject(); ②给定直接量: var person = { name : "zhangsan& ...

  7. adb help

    Android Debug Bridge version 1.0.32Revision cc6ae925e394-android -a - directs adb to listen on all i ...

  8. 小记同学一次奇葩的DNS欺骗实验失败经历

    这是一个DNS欺骗实验,使用kali的ettercap.有受害者.攻击者(虚拟机).Web服务器三台机器.受害者的事124.16.70.105虚拟机的是124.16.71.48web服务器是124.1 ...

  9. UWP 浏览本地图片及对图片的裁剪

    原文:UWP 浏览本地图片及对图片的裁剪 1.前言 准备给我的校园助手客户端添加一个修改头像的功能,但是查了好多资料都没有找到裁剪图片的简单的方法,最后才找到这个使用Launcher调用系统组件的简单 ...

  10. ArcGIS for Desktop入门教程_第三章_Desktop软件安装 - ArcGIS知乎-新一代ArcGIS问答社区

    原文:ArcGIS for Desktop入门教程_第三章_Desktop软件安装 - ArcGIS知乎-新一代ArcGIS问答社区 1 软件安装 1.1 安装前准备 请确认已经收到来自Esri中国( ...