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必 ...
随机推荐
- 关于fastjson用法
fastjson 是一个性能很好的 Java 语言实现的 JSON 解析器和生成器,来自阿里巴巴的工程师开发. public static final String toJSONString(Obje ...
- linux没有 conio.h解决的方式
conio.h不是C标准库中的头文件,在ISO和POSIX标准中均未定义. conio是Console Input/Output(控制台输入输出)的简写,当中定义了通过控制台进行数据输入和数据输出的函 ...
- web开发中../、./、/的区别
原文:web开发中../.././的区别 最近在业余时间慢慢玩起了网站开发,觉得挺有意思的.在开发过程中,老是分不清 ../.././三者之间的区别,也老是弄混,最后仔细搜索研究了一下,现在终于懂了. ...
- AngularJS 计时器
<div ng-controller="MyController"> <!--显示$scope.clock的now属性--> <h1>hello ...
- c# 自定义公共类CallFunction-调用函数信息帮助类
/// <summary> /// 调用函数信息 /// </summary> public class CallFunction { /// <summary> ...
- https://www.jianshu.com/p/4da29fa310d2
wampserver显示红色.橙色的解决方案 拿笔的小鑫 关注 2016.10.15 14:38* 字数 2643 阅读 5083评论 0喜欢 3赞赏 1 </br></br&g ...
- 调用API函数减少c#内存占用(20+m减至1m以下)
原文:调用API函数减少c#内存占用(20+m减至1m以下) c#虽然内置垃圾回收机制,但是并不能解决程序占用内存庞大的问题,如果我们仔细观察任务管理器,我们会发现一个程序如果最小化的时候,它所占用的 ...
- 不能继承于QObject的类就一定不能使用信号槽?(用一个代理类进行发射就行了)
首先不能继承QObject的情况在开发中遇到得并不多,笔者在一年多的Qt项目开发中只遇到两三次.而且都是因为引进了第三方库导致编译过程中报错. 要想解决这个问题其实不难,因为笔者遇到的问题都是想定义一 ...
- Win8Metro(C#)数字图像处理--2.9图像均值滤波
原文:Win8Metro(C#)数字图像处理--2.9图像均值滤波 [函数名称] 图像均值滤波函数MeanFilterProcess(WriteableBitmap src) [函数代码] ...
- 微信小程序把玩(十五)checkbox组件
原文:微信小程序把玩(十五)checkbox组件 不得不吐糟下checkbox默认样式真是有点略丑!!!checkbox组件为一个多选框被放到checkbox-group组中,并在checkbox-g ...