两条直线(蓝桥杯)二分枚举+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: ...
随机推荐
- 耦合 Coupling the object-oriented paradigm && data coupling
Computer Science An Overview _J. Glenn Brookshear _11th Edition 耦 两个人一起耕地 one of the benefits of the ...
- Apache与Tomcat 区别联系(转)
转自:http://www.admin10000.com/document/974.html Apache 和 Tomcat 都是web网络服务器,两者既有联系又有区别,在进行HTML.PHP.JSP ...
- Jsoncpp 数组的使用
JsonCpp 是一个C++用来处理JSON 数据的开发包.下面讲一下怎么使用JsonCpp来序列化和反序列化Json对象,以实际代码为例子. 反序列化Json对象 比如一个Json对象的字符串序列如 ...
- Div自适应高度的方法
http://www.yutheme.cn/website/index.php/content/view/39/63.html div高度自适应是个比较麻烦的问题,在朋友artery那里看到这个文章, ...
- 转:Asp.net Mvc4默认权限详细(上)
前言 上篇的菜鸟去重复之Sql的问题还没有得到满意的答案.如果哪位大哥有相关的资料解释,能够分享给我,那就太谢谢了. 以后每发表一篇博文我都会将以前遗留的问题在前言里指出,直到解决为止. 本文主要在于 ...
- Top 30 Nmap Command Examples For Sys/Network Admins
Nmap is short for Network Mapper. It is an open source security tool for network exploration, securi ...
- How To Set Up Apache with a Free Signed SSL Certificate on a VPS
Prerequisites Before we get started, here are the web tools you need for this tutorial: Google Chrom ...
- jQurey 获取当前时间
<script type="text/javascript"> $(document).ready(function () { var myDate = new Dat ...
- oracle语句随笔
oracle语句随笔 dmp数据的导入. ; --创建用户 GRANT CONNECT,RESOURCE,DBA TO memsspc; --赋值权限 --cmd 中导入命令 IMP memsspc@ ...
- AppStore提审攻略
导语: AppStore后台上传新产品的时候需要填写很多资料,看似很复杂,其实搞清楚之后也比较简单. 下面就给大家介绍一下 iTunes Connect 后台上传新APP时需要提交的资料.不要等待需 ...