两条直线(蓝桥杯)二分枚举+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: ...
随机推荐
- 【】五句话搞定JavaScript作用域
JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走遍天下都不怕... 一.“JavaScript中无块级作用域” 在Java或C# ...
- spark mllib 之线性回归
public static void main(String[] args) { SparkConf sparkConf = new SparkConf() .setAppName("Reg ...
- jbpm node signal
task-node (任务节点) 其性质和node节点一样,在没有task的时候,也都是自动执行,不等待.task-node被归类为一个等待节点,是指在task-node中的task列表中的task没 ...
- spring容器IOC创建对象<三>
问题?Spring的DI讲解.DI有几种注入方式.一.spring的DI:依赖注入给属性赋值DI定义:一个对象类的属性可以使用springDI(依赖注入)来进行赋值,但是并不是所有的类属性都适合spr ...
- Xcode Shortcuts
Description:⌘: Command ⌥: Option ⌃: Control ←↑↓→: Left, Up, Down, Right ...
- NOIP2013,复赛及同步赛,报名及比赛,专题页面
本通知的对象仅仅是福州第十九中学的学生 所有参加复赛以及同步赛的选手,请务必要仔细阅读:<关于CCF NOIP2013复赛有关事宜的通知>,里面有比赛的时间.地点.以及比赛费用的说明. 参 ...
- 强调语气<strong>和<em>标签,文字设置单独样式<span>
区别:1,<em> 表示强调,<strong> 表示更强烈的强调. 2,并且在浏览器中<em> 默认用斜体表示,<strong> 用粗体表示. 3,两个 ...
- windows下安装和配置mongoDB
上次在mac下安装和配置了mongodb,这次在windows下也尝试安装和配置mongodb. 1.首先下载mongodb压缩包,下载后解压到D盘或E盘.如下: 2.配置环境变量:桌面—计算机右键— ...
- SQL PROMPT 取消dbo前缀
SQL Prompt 无疑大大提高了开发者的效率,高效而简单,特别适合大型的数据库脚本编写,但遗憾得是至今没有可供使用的中文版本.SQL Prompt 默认对象名前面会有 dbo 前缀,在一些场合这样 ...
- graphviz - Node Shapes
Node Shapes There are three main types of shapes : polygon-based, record-based and user-defined. The ...