【bzoj 入门OJ】[NOIP 热身赛]Problem B: escape(二分答案+bfs)
2016-11-16 19:22
344 查看
Problem B: escape
Time Limit: 2 Sec Memory Limit: 128 MBSubmit: 168 Solved: 41
[Submit][Status][Web
Board]
Description
给出数字N(1<=N<=10000),X(1<=x<=1000),Y(1<=Y<=1000),代表有N个敌人分布一个X行Y列的矩阵上矩形的行号从0到X-1,列号从0到Y-1再给出四个数字x1,y1,x2,y2,代表你要从点(x1,y1)移到(x2,y2)。在移动的过程中你当然希望离敌人的距离的最小值最大化,现在请求出这个值最大可以为多少,以及在这个前提下你最少要走多少步才可以回到目标点。注意这里距离的定义为两点的曼哈顿距离,即某两个点的坐标分为(a,b),(c,d)那么它们的距离为|a-c|+|b-d|
Input
第一行给出数字N,X,Y 第二行给出x1,y1,x2,y2
下面将有N行,给出N个敌人所在的坐标
Output
在一行内输出你离敌人的距离及在这个距离的限制下,你回到目标点最少要移动多少步。
Sample Input
2 5 6 0 0 4 0 2 1 2 3
Sample Output
2 14
HINT
【题解】【二分答案+BFS】
【先将所有敌人的位置入队,由每个敌人开始扩展,求出所有点与敌人的最短距离,并将其中必经的起点和终点中小的一个距离作为二分答案的上界。】
【二分最小距离,每二分到一个答案len,就bfs判断在只经过距离敌人>=len的点是否能从起点走到终点。】
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int d[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
int q,n,m,x2,y2,x1,y1;
int dis[1010][1010],que[1000010][2],h,t,mxn;
int route[1010][1010],len,ans;
bool b[1010][1010];
inline bool check(int ll)
{
memset(route,127/3,sizeof(route));
memset(b,0,sizeof(b));
int last=route[0][0];
h=t=0; b[x2][y2]=1; route[x2][y2]=0;
que[++t][0]=x2; que[t][1]=y2;
while(h!=t)
{
h=(h%1000010)+1;
int x=que[h][0],y=que[h][1];
if(x==x1&&y==y1) break;
for(int i=0;i<4;++i)
{
int xx=x+d[i][0],yy=y+d[i][1];
if(xx>=0&&xx<n&&yy>=0&&yy<m&&dis[xx][yy]>=ll)
if(route[xx][yy]>route[x][y]+1)
{
route[xx][yy]=route[x][y]+1;
if(!b[xx][yy])
{
t=(t%1000010)+1;
que[t][0]=xx; que[t][1]=yy;
b[xx][yy]=1;
}
}
}
}
return (route[x1][y1]==last);
}
inline void qsort(int l,int r)
{
int mid;
while(l<=r)
{
mid=(l+r)>>1;
if(!check(mid))
l=mid+1,ans=mid,len=route[x1][y1];
else r=mid-1;
}
}
int main()
{
//freopen("int.txt","r",stdin);
//freopen("my.txt","w",stdout);
int i,j;
memset(dis,127/3,sizeof(dis));
scanf("%d%d%d",&q,&n,&m);
scanf("%d%d%d%d",&x2,&y2,&x1,&y1);
for(i=1;i<=q;++i)
{
int x,y;
scanf("%d%d",&x,&y);
que[++t][0]=x; que[t][1]=y;
dis[x][y]=0; b[x][y]=1;
}
while(h!=t)
{
h=(h%1000010)+1;
int x=que[h][0],y=que[h][1];
for(i=0;i<4;++i)
{
int xx=x+d[i][0],yy=y+d[i][1];
if(xx>=0&&xx<n&&yy>=0&&yy<m)
if(dis[xx][yy]>dis[x][y]+1)
{
dis[xx][yy]=dis[x][y]+1;
if(!b[xx][yy])
{
b[xx][yy]=1;
t=(t%1000010)+1;
que[t][0]=xx; que[t][1]=yy;
}
}
}
}
mxn=min(dis[x2][y2],dis[x1][y1]);
qsort(0,mxn);
printf("%d %d\n",ans,len);
return 0;
}
相关文章推荐
- 【bzoj 入门OJ】[NOIP 热身赛]Problem C: 星球联盟(并查集)
- [BZOJbegin][NOIP十连测热身赛b]escape(二分+bfs)
- bzoj 4326: NOIP2015 运输计划 (二分答案+树链剖分+树状数组)
- 【bzoj4326】[NOIP2015]运输计划 二分答案+LCA
- 【NOIP2015】【bzoj4326】运输计划 LCA+差分+二分答案
- 二分答案:Poweroj2461-入门基础之二分答案(二分法的应用)
- 【算法学习笔记】45. 二分答案 BFS路径 SJTU OJ 1031 二哥在黄山
- 【bzoj 十连测】[noip2016十连测第三场]Problem A: 平均数(二分答案+归并排序求逆序对)
- [BZOJ4326][NOIP2015]运输计划(二分答案+树上差分)
- BZOJ 4326: NOIP2015 运输计划 二分答案 树上差分
- BZOJ[4326][NOIP2015]运输计划 二分答案+树链剖分+差分
- 【BZOJ4326】【二分答案】【树上差分】NOIP2015 D2T3 运输计划 题解
- [二分答案 树链剖分] BZOJ 4326 NOIP2015 运输计划
- 【枚举】【二分答案】【分块答案】【BFS】【最大流】【Dinic】bzoj1189 [HNOI2007]紧急疏散evacuate
- BZOJ 1189 HNOI 2007 紧急疏散 evacuate 二分答案 最大流
- noip推荐系列:遥控车[字符串+高精+二分答案]
- 【BZOJ】【P2298】【HAOI2011】【problem a】【题解】【dp+二分】
- BZOJ 1196 HNOI2006 公路修建问题 二分答案+Kruskal
- BZOJ 1305 CQOI2009 dance跳舞 二分答案+最大流
- BZOJ 1038 ZJOI2008 瞭望塔 模拟退火+二分答案