题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4444

题意:给你一些n个矩形,给你一个起点,一个终点,要你求从起点到终点最少需要转多少个弯

题解:因为矩形数量很少50个,可以离散化成102*102的坐标,但是人可以贴着墙壁走,但不能穿过墙壁

所以每个点要分成9等分。建筑物的边占1/3,但是这样有漏洞。

1、当两个墙壁贴在一起,中间还可以过,所以要填补中间

2、当两个矩形的角重合,中间也可以过,要填补中间,但是只能填补中间一个点,不能填补全部的9个点。

还有一点要注意的是,起点有多个,终点也有多个,从任意一起点到任意一终点即可,因为有一些特殊数据,我的例子里面有

图建好了,直接BFS记忆化搜索即可。

AC代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <list>
#include <deque>
#include <queue>
#include <iterator>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <cctype>
#include <sstream>
using namespace std; typedef long long LL;
const int N=410;
const LL II=100000000;
const int INF=0x3f3f3f3f;
const int M=12345678;
const double PI=acos(-1.0); int sx,sy,ex,ey;
int si,sj,ei,ej;
int n,nx,ny;
int x[N],y[N];
int g[N][N],step[N][N];
int t[4][2]={1,0,-1,0,0,1,0,-1}; struct node
{
int x1,x2,y1,y2;
}rect[N]; struct xiaohao
{
int xx,yy;
int step;
}e,w,xh[M]; int nextint()
{
int f=1;
char c;
while((c=getchar())<'0'||c>'9')
if(c=='-')
f=-1;
int sum=c-'0';
while((c=getchar())>='0'&&c<='9')
sum=sum*10+c-'0';
return sum*f;
} void lisanhua(int m) //离散化
{
int i,j;
sort(x+1,x+m+1);
sort(y+1,y+m+1);
nx=1;
for(i=2;i<=m;i++)//去重
if(x[i]!=x[i-1])
x[++nx]=x[i];
ny=1;
for(i=2;i<=m;i++)//去重
if(y[i]!=y[i-1])
y[++ny]=y[i];
} int getx(int xx)//数据量大的时候可以用二分查找
{
for(int i=1;i<=nx;i++)
if(x[i]==xx)
return i;
} int gety(int yy)
{
for(int i=1;i<=ny;i++)
if(y[i]==yy)
return i;
} void add(int x1,int x2,int y1,int y2)
{
int i,j;
for(i=x1;i<=x2;i++)
for(j=y1;j<=y2;j++)
g[i][j]=1;//建筑物标记为1
} void jiantu()
{
int i,j,x1,x2,y1,y2;
memset(g,0,sizeof(g));
si=getx(sx);
sj=gety(sy);
ei=getx(ex);
ej=gety(ey); for(i=si*3;i>=si*3-2;i--)//起点,这个地方9个格子全部要标记为5
for(j=sj*3;j>=sj*3-2;j--)
g[i][j]=5;
for(i=ei*3;i>=ei*3-2;i--)//终点,这个地方9个格子全部要标记为6
for(j=ej*3;j>=ej*3-2;j--)
g[i][j]=6; for(i=1;i<=n;i++)
{
x1=getx(rect[i].x1);
y1=gety(rect[i].y1);
x2=getx(rect[i].x2);
y2=gety(rect[i].y2); add(x1*3,x2*3-2,y1*3,y2*3-2);
}
for(i=1;i<=nx;i++)//将重合的点中间补上
for(j=1;j<=ny;j++)
{
if(g[i*3-2][j*3-2]==1&&g[i*3][j*3]==1||g[i*3-2][j*3]==1&&g[i*3][j*3-2]==1)
g[i*3-1][j*3-1]=1;
if(g[i*3-1][j*3-2]==1&&g[i*3-1][j*3]==1)
g[i*3-1][j*3-1]=1;
if(g[i*3-2][j*3-1]==1&&g[i*3][j*3-1]==1)
g[i*3-1][j*3-1]=1;
}
// for(i=1;i<=3*nx;i++) //输出离散化后的图
// {
// for(j=1;j<=3*ny;j++)
// printf("%d",g[i][j]);
// printf("\n");
// }
} bool ok(int tx,int ty)
{
return (tx>=0&&tx<=3*nx&&ty>=0&&ty<=3*ny);
} void BFS()
{
int i,j,head=0,tail=0;
w.step=-1;
for(i=si*3;i>=si*3-2;i--)
for(j=sj*3;j>=sj*3-2;j--)
if(g[i][j]==5)
{
w.xx=i;w.yy=j;
xh[tail++]=w;
}
memset(step,INF,sizeof(step));
step[w.xx][w.yy]=-1;
while(head!=tail)
{
e=xh[head++];
if(head==M)
head=0;
for(i=0;i<4;i++)
{
w=e;
w.step++;
int tx=w.xx+t[i][0];
int ty=w.yy+t[i][1];
while(ok(tx,ty)&&g[tx][ty]!=1)//判断是否在界内,而且能走
{
if(w.step<step[tx][ty])
{
if(g[tx][ty]==6)
{
printf("%d\n",w.step);
return ;
}
step[tx][ty]=w.step;
w.xx=tx;
w.yy=ty;
xh[tail++]=w;
if(tail==M)
tail=0;
}
tx+=t[i][0];
ty+=t[i][1];
}
}
}
printf("-1\n");
} int main()
{
int i,j;
while(scanf("%d%d%d%d",&sx,&sy,&ex,&ey))
{
int x1,x2,y1,y2,m;
if((!sx)&&(!sy)&&(!ex)&&(!ey))
break;
if(sx==ex&&sy==ey)
{
printf("0\n");
continue;
}
m=0;
rect[0].x1=x[++m]=sx;
rect[0].y1=y[m]=sy;
rect[0].x2=x[++m]=ex;
rect[0].y2=y[m]=ey;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
if(x1>x2)//防止有的数据先是右上点再是左下点
swap(x1,x2),swap(y1,y2); x[++m]=rect[i].x1=x1;
y[m]=rect[i].y1=y1;
x[++m]=rect[i].x2=x2;
y[m]=rect[i].y2=y2;
} lisanhua(m);
jiantu();
BFS();
}
return 0;
} /*
0 0 3 3
4
2 0 4 2
0 2 2 4
4 2 6 4
2 4 4 6 100 -50 10 20
4
-100 15 -20 30
-5 25 50 100
-30 -30 70 -20
70 -20 120 80 5 -1 60 7
3
1 8 101 888
0 0 49 5
50 0 100 6 0 -1 2 1
3
-1 0 0 1
0 1 1 2
1 -2 3 0 0 0 0 10
1
0 5 5 8 0 0 0 10
1
-3 5 0 8 0 0 0 10
2
0 5 5 8
0 2 4 5 0 0 0 10
2
0 5 5 8
-2 1 0 4 0 0 0 10
2
0 0 5 8
-2 1 0 5 0 0 1 10
0 0 -1 2 1
3
-1 0 0 1
0 1 1 2
1 -2 3 0 0 -1 -1 0
9
-3 4 4 5
4 -3 5 5
-2 -3 4 -2
-3 -3 -2 4
-1 2 0 4
1 1 3 3
0 0 1 1
-2 -2 0 0
2 -2 3 0 0 0 0 0 结果应该为:
-1
3
2
1
0
0
0
0
2
1
1
5
*/

HDU 4444 Walk (离散化建图+BFS+记忆化搜索) 绝对经典的更多相关文章

  1. FZU 2092 收集水晶 bfs+记忆化搜索 or 暴力

    题目链接:收集水晶 一眼看过去,觉得是普通的bfs,初始位置有两个.仔细想了想...好像如果这样的话..........[不知道怎么说...T_T] dp[12][12][12][12][210] 中 ...

  2. HDU 1142 A Walk Through the Forest(Dijkstra+记忆化搜索)

    题意:看样子很多人都把这题目看错了,以为是求最短路的条数.真正的意思是:假设 A和B 是相连的,当前在 A 处, 如果 A 到终点的最短距离大于 B 到终点的最短距离,则可以从 A 通往 B 处,问满 ...

  3. [Swust OJ 409]--小鼠迷宫问题(BFS+记忆化搜索)

    题目链接:http://acm.swust.edu.cn/problem/409/ Time limit(ms): 1000 Memory limit(kb): 65535   Description ...

  4. FZU 2092 bfs+记忆化搜索

    晚上团队训练赛的题 和普通bfs不同的是 这是同时操纵人与影子两个单位进行的bfs 由于可能发生人和影子同时接触水晶 所以不可以分开操作 当时使用node记录人和影子的位置 然后进行两重for循环来分 ...

  5. luogu1514 [NOIp2010]引水入城 (bfs+记忆化搜索)

    我们先bfs一下看看是否能到最底下的所有点 如果不能的话,直接把不能到的那几个数一数就行了 如果能的话: 可以发现(并不可以)某格能到达的最底下的格子一定是一个连续的区间 (因为如果不连续的话,我们先 ...

  6. 【BZOJ 1415】 1415: [Noi2005]聪聪和可可 (bfs+记忆化搜索+期望)

    1415: [Noi2005]聪聪和可可 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1640  Solved: 962 Description I ...

  7. csu 最优对称路径(bfs+记忆化搜索)

    1106: 最优对称路径 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 371  Solved: 77[Submit][Status][Web Boar ...

  8. hdu 1078 FatMouse and Cheese(简单记忆化搜索)

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1078 题意:给出n*n的格子,每个各自里面有些食物,问一只老鼠每次走最多k步所能吃到的最多的食物 一道 ...

  9. hdu 4753 Fishhead’s Little Game 博弈论+记忆化搜索

    思路:状态最多有2^12,采用记忆化搜索!! 代码如下: #include<iostream> #include<stdio.h> #include<algorithm& ...

随机推荐

  1. spring整合springMVC、mybatis、hibernate、mongodb框架

    开发环境 eclipse Mars 4.5 JDK 1.7 框架 spring 4.0.5 mybatis 3.2.7 hibernate 4.3.6 mongodb 1.7 数据库 MySQL 5. ...

  2. LeetCode::Remove Duplicates from Sorted List II [具体分析]

    Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numb ...

  3. htm初学笔记

    一.什么是html HTML(HyperText Markup Language):超文本标记语言,一种纯文本类型的语言 --使用带有尖括号的“标记”将网页中的内容逐一标识出来 用来设计网页的标记语言 ...

  4. javaScrip中的“?”

    例如window.location.href="./user/userUpdate?id="+id; 在这里“?”是传入参数或是带个参数id,这样就可以获得到主键了. String ...

  5. Linux CentOS PhpMyAdmin安装

    安装好PHP,Apache和MySQL程序后,为了管理MySQL数据库,我们需要安装phpMyAdmin程序.下面是关于如何在centos安装phpMyAdmin程序的方法.1.管理员root身份登录 ...

  6. win7 安装 IIS

    和xp不同,xp安装 IIS需要下载额外的软件包. 步骤 1,依次打开 "控制面板" -> "程序" ->"打开或关闭windows功能& ...

  7. javascript 闭包的理解

    1 需要明白概念: 执行环境 变量对象,活动对象 作用域,作用域链 闭包 垃圾处理机制 闭包陷阱

  8. MySQL 使用索引扫描来做排序

    MySQL有两种方式可以生成有序的结果:通过排序操作:或者按照索引顺序扫描:如果EXPLAIN 出来的结果的type列的值为“index”,则说明MySQL使用了索引扫描来做排序(不要和Extra列的 ...

  9. $().text() 和 $().html()

    1:性能 stackflow:http://stackoverflow.com/questions/1910794/what-is-the-difference-between-jquery-text ...

  10. JS原型的剖析与理解

    原型相关的概念 关于面向对象的概念 类 class 在js中就是构造函数 在传统的面向对象语言中,使用一个叫类的东西定义模版,然后使用模版创建对象 在构造方法中也具有类似的功能,因此称其为类 实例与对 ...