bzoj1038题解
【题意分析】
求一个下凸壳与一段折线的距离。
【解题思路】
先把直线按斜率排序,求出下凸壳,然后枚举所有的顶点的x坐标求最短y坐标差,复杂度O(nlog2n)。
【参考代码】
#include <algorithm>
#include <cstdio>
#define REP(i,low,high) for(register int i=(low);i<=(high);++i)
#define __function__(type) /*__attribute__((optimize("-O2"))) inline */type
#define __procedure__ /*__attribute__((optimize("-O2"))) inline */void
using namespace std; //defs {
#include <cmath>
template<typename real>
inline __function__(bool) fequals(
const real&one,const real&another,const real&eps=1e-
) {return fabs(one-another)<eps;}
template<typename real>
inline __function__(bool) funequals(
const real&one,const real&another,const real&eps=1e-
) {return fabs(one-another)>=eps;}
//} defs //geometry {
template<typename T=double> struct Point
{
T x,y; Point(const T&_x=,const T&_y=):x(_x),y(_y) {}
__function__(bool) operator==(const Point<T>&thr)const
{
return fequals(x,thr.x)&&fequals(y,thr.y);
}
__function__(bool) operator!=(const Point<T>&thr)const
{
return funequals(x,thr.x)||funequals(y,thr.y);
}
__function__(Point<T>) operator+(const Point<T>&thr)const
{
return Point<T>(x+thr.x,y+thr.y);
}
__function__(Point<T>) operator-(const Point<T>&thr)const
{
return Point<T>(x-thr.x,y-thr.y);
}
__function__(Point<T>) operator*(const T&lambda)const
{
return Point<T>(x*lambda,y*lambda);
}
__function__(Point<double>) operator/(const T&lambda)const
{
return Point<double>(double(x)/lambda,double(y)/lambda);
}
__function__(double) theta()const
{
return x>?(y<)**M_PI+atan(y/x):M_PI+atan(y/x);
}
__function__(double) theta_x()const{return x?atan(y/x):M_PI/;}
__function__(double) theta_y()const{return y?atan(x/y):M_PI/;}
};
template<typename T>
inline __function__(T) dot_product(const Point<T>&A,const Point<T>&B)
{
return A.x*B.x+A.y*B.y;
}
template<typename T>
inline __function__(T) cross_product(const Point<T>&A,const Point<T>&B)
{
return A.x*B.y-A.y*B.x;
}
template<typename T>
inline __function__(double) Euclid_distance(const Point<T>&A,const Point<T>&B)
{
return sqrt(pow(A.x-B.x,),pow(A.y-B.y,));
}
template<typename T>
inline __function__(T) Manhattan_distance(const Point<T>&A,const Point<T>&B)
{
return fabs(A.x-B.x)+fabs(A.y-B.y);
}
struct kbLine
{
//line:y=kx+b
double k,b; kbLine(const double&_k=,const double&_b=):k(_k),b(_b) {}
__function__(bool) operator==(const kbLine&thr)const
{
return fequals(k,thr.k)&&fequals(b,thr.b);
}
__function__(bool) operator!=(const kbLine&thr)const
{
return funequals(k,thr.k)||funequals(b,thr.b);
}
__function__(bool) operator<(const kbLine&thr)const{return k<thr.k;}
__function__(bool) operator>(const kbLine&thr)const{return k>thr.k;}
template<typename T>
__function__(bool) build_line(const Point<T>&A,const Point<T>&B)
{
return fequals(A.x,B.x)?:(k=double(A.y-B.y)/(A.x-B.x),b=A.y-k*A.x,);
}
__function__(double) theta_x()const{return atan(k);}
__function__(double) theta_y()const{return theta_x()-M_PI/;}
__function__(double) get(const double&x)const{return k*x+b;}
};
__function__(bool) parallel(const kbLine&A,const kbLine&B)
{
return A!=B&&(fequals(A.k,B.k)||A.k!=A.k&&B.k!=B.k);
}
__function__(Point<double>*) cross(const kbLine&A,const kbLine&B)
{
if(A==B||parallel(A,B)) return NULL; double _x=double(B.b-A.b)/(A.k-B.k);
Point<double>*ret=new Point<double>(_x,A.k*_x+A.b); return ret;
}
//} geometry static int n; double x[],y[]; int stack[]; kbLine L[]; int main()
{
scanf("%d",&n); REP(i,,n) scanf("%lf",x+i); REP(i,,n) scanf("%lf",y+i);
REP(i,,n-) L[i].build_line(Point<>(x[i],y[i]),Point<>(x[i+],y[i+]));
sort(L+,L+n); int top=stack[]=; REP(i,,n-)
{
for(;i<=n&&(L[i]==L[stack[top]]||parallel(L[i],L[stack[top]]));++i);
for(;i<=n&&top>;--top)
{
Point<>*last=cross(L[stack[top-]],L[stack[top]]),
* now=cross(L[ i ],L[stack[top]]);
if(last->x<now->x) break; delete last; delete now;
}
stack[++top]=i;
}
double ans=1e10; int j=;
REP(i,,n)
{
for(;L[stack[j]].get(x[i])>L[stack[j-]].get(x[i]);++j);
ans=min(ans,L[stack[--j]].get(x[i])-y[i]);
}
REP(i,,top)
{
Point<>*now=cross(L[stack[i-]],L[stack[i]]);
j=upper_bound(x+,x+n+,now->x)-x; kbLine tmp;
tmp.build_line(Point<>(x[j-],y[j-]),Point<>(x[j],y[j]));
ans=min(ans,now->y-tmp.get(now->x)); delete now;
}
return printf("%.3lf\n",ans),;
}
bzoj1038题解的更多相关文章
- 【bzoj1038】瞭望塔
[bzoj1038]瞭望塔 题意 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安.我们将H村抽象为一维的轮廓.如下图所示 我们可以用一条山的上方轮廓折 ...
- 【BZOJ1038】[ZJOI2008]瞭望塔 半平面交
[BZOJ1038][ZJOI2008]瞭望塔 Description 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安.我们将H村抽象为一维的轮廓.如 ...
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
- Codeforces Round #353 (Div. 2) ABCDE 题解 python
Problems # Name A Infinite Sequence standard input/output 1 s, 256 MB x3509 B Restoring P ...
- 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解
题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...
- 2016ACM青岛区域赛题解
A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- poj1399 hoj1037 Direct Visibility 题解 (宽搜)
http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...
随机推荐
- secureCRT The remote system refused the connection.解决办法
使用远程登录工具SecureCRT登陆ubuntu的时候遇到了这个问题: secureCRT The remote system refused the connection 这个问题的原因是是Ubu ...
- linux挂载群辉的NFS共享文件夹
mount -t nfs 192.168.137.136:/volume1/NFSfile /NFSfile -o proto=tcp -o nolock df -h #查看挂载点
- SQL关于:警告: 聚合或其他 SET 操作消除了空值。
方法一: create table tb ( id int, num int ) insert into tb select 1,10 insert into tb select 1,20 inser ...
- classmethod和staticmethod
假设有这么一个 class class Date(object): def __init__(self, day=0, month=0, year=0): self.day = day self.mo ...
- 自定义checkbox,radio样式
input[type=radio] { margin-right: 5px; cursor: pointer; font-size: 14px; width: 15px; height: 15px; ...
- OpenGL Download
{ https://www.opengl.org/ }
- Java——main()方法
3.1 main()方法 由于java虚拟机需要调用类的main()方法,所以该方法的访问权限必须是public,又因为java虚拟机在执行main()方法时不必创建对象,所以该方法必须是static ...
- Java中遍历数组的三种方式复习
1 for循环遍历 通常遍历数组都是使用for循环来实现.遍历一维数组很简单,遍历二维数组需要使用双层for循环,通过数组的length属性可获得数组的长度. 程序示例: package captai ...
- tarjan求强联通分量
tarjan求强联通分量 变量含义说明: pre[i]:i点的被访问的时钟编号,被分配后保持不变 low[i]:i点能访问的最先的点的时钟编号,随子节点改变 scc_no[i]:i点所在的强联通分量的 ...
- elipse手机设备显示Target unknown或者offline解决方法
参考资料: http://blog.csdn.net/yuanjingjiang/article/details/11297433 http://www.educity.cn/wenda/153487 ...