1038: [ZJOI2008]瞭望塔

半平面交。

半平面指的就是一条直线的左面(也不知道对不对)

半平面交就是指很多半平面的公共部分。

这道题的解一定在各条直线的半平面交中。

而且瞭望塔只可能在各个点或者半平面交折线的拐点处。

求出半平面交,枚举即可。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define eps 1e-7
using namespace std;
const int maxn = 300 + 10;

struct Point {
    double x,y;
}p[maxn],t;

struct Line {
    double k,b;

    void init(Point p1,Point p2) {
        k=(p1.y-p2.y)/(p1.x-p2.x);
        b=p2.y-k*p2.x;
    }
}l[maxn],s[maxn];

int n,sp;
double res=1e11;

bool cmp(Line x,Line y) {
    if(abs(x.k-y.k)<eps) return x.b<y.b;
    return x.k<y.k;
}

Point inter(Line l1,Line l2) {
    Point res;
    res.x=(l2.b-l1.b)/(l1.k-l2.k);
    res.y=l1.k*res.x+l1.b;
    return res;
}

void push(Line l) {
    while(sp>=2 && inter(s[sp],l).x < inter(s[sp-1],s[sp]).x) sp--;
    s[++sp]=l;
}

double f(double x) {
    double res=0;
    for(int i=1;i<=sp;i++) res=max(res,s[i].k*x+s[i].b);
    return res;
}

double g(double x) {
    int i;
    for(i=n;i&&x<p[i].x;i--);
    return p[i].y+(x-p[i].x)/(p[i+1].x-p[i].x)*(p[i+1].y-p[i].y);
}

int main() {
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%lf",&p[i].x);
    for(int i=1;i<=n;i++) scanf("%lf",&p[i].y);
    for(int i=1;i<n;i++) l[i].init(p[i],p[i+1]);
    sort(l+1,l+n,cmp);
    for(int i=1;i<n;i++) if(i==n-1 || abs(l[i].k-l[i+1].k)>eps) push(l[i]);

    for(int i=1;i<=n;i++) res=min(res,f(p[i].x)-p[i].y);
    for(int i=1;i<sp;i++) {
        t=inter(s[i],s[i+1]);
        res=min(res,t.y-g(t.x));
    }
    printf("%.3lf\n",res);
    return 0;
}
时间: 2024-12-29 11:53:01

1038: [ZJOI2008]瞭望塔的相关文章

BZOJ 1038 ZJOI2008 瞭望塔 模拟退火+二分答案

题目大意:给定一条折线,要求选择一个点建立高度为h的瞭望塔,要求瞭望塔塔顶可以看到折线上的每一个点,求h的最小值 正解:半平面交 不会! 于是我们选择模拟退火来寻找瞭望塔的横坐标 确定瞭望塔的高度的时候我们选择二分处理 对于二分的每一个值 我们把折线上的端点从左到右枚举 瞭望塔的塔尖到每个端点的连线必须从左到右逆时针顺序 否则就会被遮挡 如图,塔尖到点2的连线在到点1的连线的顺时针方向,故点1被遮挡,该高度不可行 写完交上去各种秒WA,最后发现我的INF又不够大...我沙茶,我蒟蒻,我这个不长记

【BZOJ】1038: [ZJOI2008]瞭望塔

http://www.lydsy.com/JudgeOnline/problem.php?id=1038 题意:给出n个x轴各不相同的整点且升序,n<=300,求这些点依次连接后折线的上面取一个点(x, y)使得:x0<=x<=xn,且这个点可以看得到所有线段的所有点.要求这些点到(垂直到)折线的y值之差最小. #include <cstdio> #include <cstring> #include <cmath> #include <stri

BZOJ 1038 ZJOI2008 瞭望塔 半平面交

题目大意及模拟退火题解:见 http://blog.csdn.net/popoqqq/article/details/39340759 这次用半平面交写了一遍--求出半平面交之后.枚举原图和半平面交的每一个点,求出答案就可以 #include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define M 310 #define

【BZOJ 1038】 [ZJOI2008]瞭望塔

1038: [ZJOI2008]瞭望塔 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 973  Solved: 428 [Submit][Status] Description 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安.我们将H村抽象为一维的轮廓.如下图所示 我们可以用一条山的上方轮廓折线(x1, y1), (x2, y2), -. (xn, yn)来描述H村的形状,这里x1 < x2 <

bzoj千题计划126:bzoj1038: [ZJOI2008]瞭望塔

http://www.lydsy.com/JudgeOnline/problem.php?id=1038 本题可以使用三分法 将点按横坐标排好序后 对于任意相邻两个点连成的线段,瞭望塔的高度 是单峰函数,而且是下凸函数 感性理解单峰就是 瞭望塔建的靠左,为了能看到右边的,要高一点 瞭望塔建的靠右,为了能看到左边的,要高一点 所以 枚举所有线段,三分线段上建造瞭望塔的位置,所有线段上的瞭望塔高度取最小 #include<cmath> #include<cstdio> #include

【BZOJ1038】[ZJOI2008]瞭望塔 半平面交

[BZOJ1038][ZJOI2008]瞭望塔 Description 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安.我们将H村抽象为一维的轮廓.如下图所示 我们可以用一条山的上方轮廓折线(x1, y1), (x2, y2), …. (xn, yn)来描述H村的形状,这里x1 < x2 < …< xn.瞭望塔可以建造在[x1, xn]间的任意位置, 但必须满足从瞭望塔的顶端可以看到H村的任意位置.可见在不同的位置建造瞭望塔,所需要建造的

[ZJOI2008]瞭望塔

题目描述 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安. 我们将H村抽象为一维的轮廓.如下图所示 我们可以用一条山的上方轮廓折线(x1, y1), (x2, y2), …. (xn, yn)来描述H村的形状,这里x1 < x2 < …< xn.瞭望塔可以建造在[x1, xn]间的任意位置, 但必须满足从瞭望塔的顶端可以看到H村的任意位置.可见在不同的位置建造瞭望塔,所需要建造的高度是不同的.为了节省开支,dadzhi村长希望建造的塔高度

P2600 [ZJOI2008]瞭望塔

题目描述 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安. 我们将H村抽象为一维的轮廓.如下图所示 我们可以用一条山的上方轮廓折线(x1, y1), (x2, y2), -. (xn, yn)来描述H村的形状,这里x1 < x2 < -< xn.瞭望塔可以建造在[x1, xn]间的任意位置, 但必须满足从瞭望塔的顶端可以看到H村的任意位置.可见在不同的位置建造瞭望塔,所需要建造的高度是不同的.为了节省开支,dadzhi村长希望建造的塔高度

【半平面交】bzoj1038 [ZJOI2008]瞭望塔

http://m.blog.csdn.net/blog/qpswwww/44105605 #include<cstdio> #include<cmath> #include<algorithm> using namespace std; #define EPS 0.0000001 #define N 311 typedef double db; const db PI=acos(-1.0); struct Point{db x,y;}; typedef Point Ve