两条直线(蓝桥杯)二分枚举+RMQ
给定平面上n个点。
求两条直线,这两条直线互相垂直,而且它们与x轴的夹角为45度,并且n个点中离这两条直线的曼哈顿距离的最大值最小。
两点之间的曼哈顿距离定义为横坐标的差的绝对值与纵坐标的差的绝对值之和,一个点到两条直线的曼哈顿距离是指该点到两条直线上的所有点的曼哈顿距离中的最小值。
第一行包含一个数n。
接下来n行,每行包含两个整数,表示n个点的坐标(横纵坐标的绝对值小于109)。
1 0
0 1
2 1
1 2
对于30%的数据,n<=100。
对于另外30%的数据,坐标范的绝对值小于100。
对于100%的数据,n<=105。
分析:因为这两条直线是垂直的,为了处理方便把坐标系逆时针旋转45度,然后这两个直线就是垂直于坐标轴的,接着把坐标按照x坐标从小到大排序,然后二分答案,对于每个二分的答案mid,按照x坐标从左到右枚举,直到找到最大的xj满足xj-xi<=mid*2,在[i,j]区间内的点都在垂直线的范围内,剩下的[1,i-1]和[j+1,n]则属于水平线范围,如果满足在[1,i-1]和[j+1,n]找到最大y和最小y的差值<=mid*2则把答案向更优二分,否则增大mid的值。
求区间内的最大值和最小值可以用RMQ来求,因为此题比较特殊,可以分别从左,和从右遍历一边从两端来记录最大值和最小值
#include"stdio.h"
#include"string.h"
#include"math.h"
#define M 100009
#include"vector"
#include"queue"
#include"stdlib.h"
#include"deque"
#define eps 1e-3
#define PI acos(-1.0)
#define inf 10000000000000LL
#include"algorithm"
using namespace std;
struct node
{
double x,y;
bool operator<(const node &p)const
{
return x<p.x;
}
}p[M];
int Log[M];
double maxl[M],minl[M],maxr[M],minr[M],val[M];
double dp_max[M][],dp_min[M][];
void initLog()
{
Log[]=-;
for(int i=;i<M;i++)
{
Log[i]=(i&(i-))==?Log[i-]+:Log[i-];
}
}
void RMQ(int n)
{
int m=Log[n];
for(int i=;i<=n;i++)
dp_max[i][]=dp_min[i][]=p[i].y;
for(int j=;j<=m;j++)
{
for(int i=;i<=n+-(<<j);i++)
{
dp_max[i][j]=max(dp_max[i][j-],dp_max[i+(<<(j-))][j-]);
dp_min[i][j]=min(dp_min[i][j-],dp_min[i+(<<(j-))][j-]);
}
}
}
double lcp_max(int l,int r)
{
int m=Log[r-l+];
return max(dp_max[l][m],dp_max[r+-(<<m)][m]);
}
double lcp_min(int l,int r)
{
int m=Log[r-l+];
return min(dp_min[l][m],dp_min[r+-(<<m)][m]);
}
double max(double a,double b)
{
return a>b?a:b;
}
double min(double a,double b)
{
return a<b?a:b;
}
node ver(node a)
{
double L=sqrt(a.x*a.x+a.y*a.y);
double du=asin(a.y/L);
du+=PI/;
a.x=L*cos(du);
a.y=L*sin(du);
return a;
}
//分别从两端记录最大值和最小值
void init(int n)
{
maxl[]=minl[]=p[].y;
for(int i=;i<=n;i++)
{
maxl[i]=max(p[i].y,maxl[i-]);
minl[i]=min(p[i].y,minl[i-]);
}
maxr[n]=minr[n]=p[n].y;
for(int i=n-;i>=;i--)
{
maxr[i]=max(p[i].y,maxr[i+]);
minr[i]=min(p[i].y,minr[i+]);
}
}
int judge(int n,double mid)
{
int left=,right=;
for(left=;left<=n;left++)
{
double up=-inf;
double down=inf;
while(right<=n&&p[right].x-p[left].x<=mid*)
{
right++;
}
if(left>)
{
up=max(up,lcp_max(,left-));
down=min(down,lcp_min(,left-));
}
if(right<=n)
{
up=max(up,lcp_max(right,n));
down=min(down,lcp_min(right,n));
}
if(up-down<=mid*)
return ;
}
return ;
}
int main()
{
int n;
initLog();
while(scanf("%d",&n)!=-)
{
for(int i=;i<=n;i++)
{
scanf("%lf%lf",&p[i].x,&p[i].y);
p[i]=ver(p[i]);
}
sort(p+,p+n+);
double l=,r=max(p[n].x-p[].x,maxl[n]-minl[n]);
double mid;
//init(n);
RMQ(n);
while(fabs(r-l)>eps)
{
mid=(l+r)/;
if(judge(n,mid))
{
r=mid;
}
else
{
l=mid;
}
}
printf("%.1lf\n",r*sqrt(2.0));
}
return ;
}
两条直线(蓝桥杯)二分枚举+RMQ的更多相关文章
- 求空间内两条直线的最近距离以及最近点的坐标(C++)
关键词:空间几何 用途:总有地方会用到吧 文章类型:C++函数展示 @Author:VShawn(singlex@foxmail.com) @Date:2016-11-19 @Lab: CvLab20 ...
- 计算两条直线的交点(C#)
PS:从其他地方看到的源码是有问题的.下面是修正后的 /// <summary> /// 计算两条直线的交点 /// </summary> /// <param name ...
- 判断两条直线的位置关系 POJ 1269 Intersecting Lines
两条直线可能有三种关系:1.共线 2.平行(不包括共线) 3.相交. 那给定两条直线怎么判断他们的位置关系呢.还是用到向量的叉积 例题:POJ 1269 题意:这道题是给定四个点p1, ...
- POJ1269:Intersecting Lines(判断两条直线的关系)
题目:POJ1269 题意:给你两条直线的坐标,判断两条直线是否共线.平行.相交,若相交,求出交点. 思路:直线相交判断.如果相交求交点. 首先先判断是否共线,之后判断是否平行,如果都不是就直接求交点 ...
- poj 1269(两条直线交点)
Intersecting Lines Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 13481 Accepted: 59 ...
- CodeForces - 961D:Pair Of Lines (几何,问两条直线是否可以覆盖所有点)
You are given n points on Cartesian plane. Every point is a lattice point (i. e. both of its coordin ...
- C++ 根据两点式方法求直线并求两条直线的交点
Line.h #pragma once //Microsoft Visual Studio 2015 Enterprise //根据两点式方法求直线,并求两条直线的交点 #include"B ...
- C# 判断两条直线距离
本文告诉大家获得两条一般式直线距离 一般式的意思就是 Ax+By+C=0" role="presentation">Ax+By+C=0Ax+By+C=0 如果有两个 ...
- 2018-7-31-C#-判断两条直线距离
title author date CreateTime categories C# 判断两条直线距离 lindexi 2018-07-31 14:38:13 +0800 2018-05-08 10: ...
随机推荐
- DELPHI2007 安装ACTIVEX插件的方法
先新建一个Package file----NEW-----Package Delphi for win32, 再在Component->Import Component里面添加好Activ ...
- Oracle数值处理函数 (绝对值、取整...)
1.绝对值:abs() select abs(-2) value from dual; 2.取整函数(大):ceil() select ceil(-2.001) value from du ...
- php的异步处理
在PHP Web程序中,发送手机短信.电子邮件.转换视频格式.记录日志.数据挖掘采集等,都是比较耗时的操作. 为了增强用户体验,需要将这些操作转为异步执行 PHP Web程序中的短耗时异步处理 前 ...
- 【No.2 Ionic】Android打包
项目做完之后 接下来就是打包操作了,接下来直接说Android 打包操作 生成签名证书 keytool -genkey -alias vincentguo -keyalg RSA -validity ...
- ubuntu 64bit arm-linux-gcc: No such file or directory 解决
通过下面这个解决 ubuntu 64bit arm-linux-gcc: No such file or directory 安装 sudo apt-get install lsb-core解决 h ...
- 异常处理与MiniDump详解(4) MiniDump
http://blog.csdn.net/vagrxie/article/details/4398721 异常处理与MiniDump详解(4) MiniDump 分类: [Wi ...
- Android项目框架升级尝鲜OkHttp
本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 随着项目日趋稳定,需求不再总是变化,那么是时间来整理下项目了.先简单介绍下,本项目最初使用loop4 ...
- Struts Upload上传文件
1.Unable to find 'struts.multipart.saveDir' property setting. Defaulting to javax.servlet.context.te ...
- Qt操作Oracle
很久以前写过<Qt数据库操作>的一篇文章,在操作数据库的时候,温习了一下!感觉很好!但在操作Oracle数据库时又遇到了一些问题.在使用QSqlRelationalTableModel操纵 ...
- Qt自定义model
前面我们说了Qt提供的几个预定义model.但是,面对变化万千的需求,那几个model是远远不能满足我们的需要的.另外,对于Qt这种框架来说,model的选择首先要能满足绝大多数功能的需要,这就是说, ...