二叉树666

导航

 

开车出行(car)
【题目描述】
 在 2117 年*国为了缓解交通压力开发了空中汽车,为了保证夜间行驶的安全在各个路段安
装了一系列路灯进行照明。已知路灯的照明范围是一个以路灯所在的点为顶点的道路最低的
直线为底边的等腰直角三角形。汽车的行驶区域必须有路灯的照明。我们为了简化问题将道
路简化为一条直线。建立平面直角坐标系,并定义道路的最低点所在的直线为 x 轴。给定所
有路灯在直角坐标系的位置以及一个车辆需要从点 a 行驶到点 b。问这辆汽车所能行驶的最
高高度。
【输入格式】
第一行一个整数 n 表示路灯的数量
接下来 n 行每行两个整数(x,y)表示第 i 个路灯所在的位置。
第 n+2 行两个整数 x1,x2 表示 a,b 两点的 x 坐标位置
输入数据保证 n<=100000 所有的坐标均为整数且绝对值小于等于 10000
【输出格式】
一个数表示能够行驶的最高高度
精确到小数点后两位小数。
本题采用实数比较的方式进行答案正确性判定
【样例输入】
3
1 1
3 2
5 1
2 5
【样例输出】
0.50

解析:这是一道二分答案的题,部分分做法是求出每个点最高飞行高度

详情见代码

#include<iostream>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
#define MAXN 100005
#define MAXM 40005
#define INF 0x3f3f3f3f

struct hehe
{
 int x,y;
}c[MAXN];
int a[MAXM];
int n,an;
double ans;
int xa,xb;
int l = 0,r = 100000;
bool cmp(hehe x,hehe y)
{
 return x.x - x.y < y.x - y.y;
}

void rd()
{
 scanf("%d",&n);
 for(int i = 1; i <= n; i ++)
 {
  scanf("%d%d",&c[i].x,&c[i].y);
  c[i].x *= 2;//由于交点是0.5的倍数,所以为了方便转换成整数
  c[i].y *= 2;
 }
 scanf("%d%d",&xa,&xb);
 if(xa > xb)
  swap(xa,xb);
 xa *= 2;
 xb *= 2;
 
 sort(c+1,c+n+1,cmp);//按左端点排序
}

bool judge(int o)//飞行高度o时是否可行
{
 int  p = xa;//开始不被照射到的是起点
 int h;
 for(int i = 1; i <= n; i ++)//枚举所有灯
 {
  h = c[i].y - o;
  if(c[i].x - h > p)//如果灯覆盖不到最前面被照射的,返回0
  {
   return 0;
  }
  else
  {
   p = c[i].x + h;//最远可覆盖地点
  }
  if(p >= xb)//终点也被覆盖到了,就返回1
   return 1;
 }
 return 0;
 }

int main()
{
 rd();
 int mid;
 /*以下是二分答案*/
 while(l + 3 < r)//+3是为了防止+1,-1搞不清 留一段区间
 {
  mid = (l+r)>>1;
  if(judge(mid))
   l = mid;
  else
   r = mid;
 }
 double ans;
 for(int i = r; i >= l; i --)//找到最大可飞行,输出
  if(judge(i))
  {
   ans = i;
   printf("%.2lf",ans/2);
   break;
  }
 return 0;
 }
 /*
 3
1 1
3 2
5 1
2 5
 */

posted on 2017-10-08 16:49  江入网络流  阅读(203)  评论(0)    收藏  举报