HDU 4444 Walk (离散化建图+BFS+记忆化搜索) 绝对经典
题目地址: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+记忆化搜索) 绝对经典的更多相关文章
- FZU 2092 收集水晶 bfs+记忆化搜索 or 暴力
题目链接:收集水晶 一眼看过去,觉得是普通的bfs,初始位置有两个.仔细想了想...好像如果这样的话..........[不知道怎么说...T_T] dp[12][12][12][12][210] 中 ...
- HDU 1142 A Walk Through the Forest(Dijkstra+记忆化搜索)
题意:看样子很多人都把这题目看错了,以为是求最短路的条数.真正的意思是:假设 A和B 是相连的,当前在 A 处, 如果 A 到终点的最短距离大于 B 到终点的最短距离,则可以从 A 通往 B 处,问满 ...
- [Swust OJ 409]--小鼠迷宫问题(BFS+记忆化搜索)
题目链接:http://acm.swust.edu.cn/problem/409/ Time limit(ms): 1000 Memory limit(kb): 65535 Description ...
- FZU 2092 bfs+记忆化搜索
晚上团队训练赛的题 和普通bfs不同的是 这是同时操纵人与影子两个单位进行的bfs 由于可能发生人和影子同时接触水晶 所以不可以分开操作 当时使用node记录人和影子的位置 然后进行两重for循环来分 ...
- luogu1514 [NOIp2010]引水入城 (bfs+记忆化搜索)
我们先bfs一下看看是否能到最底下的所有点 如果不能的话,直接把不能到的那几个数一数就行了 如果能的话: 可以发现(并不可以)某格能到达的最底下的格子一定是一个连续的区间 (因为如果不连续的话,我们先 ...
- 【BZOJ 1415】 1415: [Noi2005]聪聪和可可 (bfs+记忆化搜索+期望)
1415: [Noi2005]聪聪和可可 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1640 Solved: 962 Description I ...
- csu 最优对称路径(bfs+记忆化搜索)
1106: 最优对称路径 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 371 Solved: 77[Submit][Status][Web Boar ...
- hdu 1078 FatMouse and Cheese(简单记忆化搜索)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1078 题意:给出n*n的格子,每个各自里面有些食物,问一只老鼠每次走最多k步所能吃到的最多的食物 一道 ...
- hdu 4753 Fishhead’s Little Game 博弈论+记忆化搜索
思路:状态最多有2^12,采用记忆化搜索!! 代码如下: #include<iostream> #include<stdio.h> #include<algorithm& ...
随机推荐
- NuGet学习笔记(2)——使用图形化界面打包自己的类库
上文NuGet学习笔记(1) 初识NuGet及快速安装使用说到NuGet相对于我们最重要的功能是能够搭建自己的NuGet服务器,实现公司内部类库的轻松共享更新.在安装好NuGet扩展后,我们已经能够通 ...
- 在Ubuntu下构建Bullet以及执行Bullet的样例程序
在Ubuntu下构建Bullet以及执行Bullet的样例程序 1.找到Bullet的下载页,地址是:https://code.google.com/p/bullet/downloads/list 2 ...
- android中广播接收SD卡状态
mReceiver = new BroadcastReceiver() { //add by mengmeng.chen begin public void onReceive(Context con ...
- 四、Solr数据源配置(JNDI、DIH)及定时重做索引
简介 Solr支持很多种创建索引的方式,包括网页,xml以及数据库,因为我这边做的是企业级的搜索,所以用的是数据库建立索引.其实从数据库建立索引,很大程度上取决于原来的数据库设计. 从数据库建立索引, ...
- linux od命令
用户通常使用od命令查看特殊格式的文件内容.通过指定该命令的不同选项可以以十进制.八进制.十六进制和ASCII码来显示文件.od命令系统默认的显示方式是八进制,这也是该命令的名称由来(Octal Du ...
- css行高line-height的用法(转)
本文导读: “行高“指一行文子的高度,具体来说是指两行文子间基线间的距离.在CSS,line-height被用来控制行与行之间的垂直距离.line- height 属性会影响行框的布局.在应用到一个块 ...
- css部分总结
10.19HTML总结 1.<!DOCTYPE HTML>声明:告知浏览器文档使用哪种HTML或者XHTML规范,该标签可声明三种DTD(文档类型定义)类型:严格版本.过渡版本以及基于框架 ...
- SQL从入门到基础 - 07 抑制重复数据
一.去掉数据重复 distinct 1. Select FDepartment from T_Employee →select distinct FDepartment from T_Employee ...
- oracle获得每周,每月,每季度,每年的第一天
当前年月日 SELECT trunc(sysdate) , trunc(sysdate,'dd') FROM dual 当年第一天 SELECT trunc(sysdate,'yyyy') FRO ...
- Google推出iOS功能性UI测试框架EarlGrey
经过了一段时间的酝酿后,Google很高兴地宣布了EarlGrey,一款针对于iOS的功能性UI测试框架.诸如YouTube.Google Calendar.Google Photos.Google ...