zoukankan      html  css  js  c++  java
  • bzoj 1038: [ZJOI2008]瞭望塔 [半平面交]

    1038: [ZJOI2008]瞭望塔

    题意:一个山形轮廓线,建一个瞭望塔能看到所有点,求最小高度。


    注意是山形

    相邻两个点连线,半平面交,保留上面的。

    不会出现一个点和隔着一些点的另一个点连线贡献的情况,因为瞭望塔一定高于最高点

    然后是个线性分段函数,枚举最值点...


    md有个点一直过不了,怒加特判

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    #define y1 y1z
    using namespace std;
    typedef long long ll;
    const double eps = 1e-9;
    const int N = 10005;
    
    inline int read() {
        char c = getchar(); int x = 0, f = 1;
        while(c < '0' || c > '9') {if(c=='-')f=-1; c=getchar();}
        while(c >= '0' && c <= '9') {x=x*10+c-'0'; c=getchar();}
        return x * f;
    }
    
    inline double _abs(double x) {return x < 0 ? -x : x;}
    inline int sgn(double x) {return _abs(x) < eps ? 0 : (x < 0 ? -1 : 1);}
    
    struct meow {
    	double x, y;
    	meow(double x = 0, double y = 0) : x(x), y(y) {}
    	bool operator <(const meow &r) const {return sgn(x - r.x) == 0 ? sgn(y - r.y) < 0 : sgn(x - r.x) < 0;}
    	void print() {printf("(%lf, %lf)
    ", x, y);}
    } ;
    typedef meow Vector; typedef Vector Point;
    meow operator + (meow a, meow b) {return meow(a.x + b.x, a.y + b.y);}
    meow operator - (meow a, meow b) {return meow(a.x - b.x, a.y - b.y);}
    meow operator * (meow a, double b) {return meow(a.x * b, a.y * b);}
    meow operator / (meow a, double b) {return meow(a.x / b, a.y / b);}
    
    double operator * (meow a, meow b) {return a.x * b.x + a.y * b.y;}
    double operator ^ (meow a, meow b) {return a.x * b.y - a.y * b.x;}
    struct Line {
    	Point s, t, v;
    	Line() {}
    	Line(Point s, Point t) : s(s), t(t) {v = t - s;}
    } ;
    
    bool on_left(Point a, Line l) {
    	return sgn(l.v ^ (a - l.s)) >= 0;
    }
    bool is_lsi(Line l1, Line l2) {
    	return sgn((l2.s - l1.s) ^ l1.v) != sgn((l2.t - l1.s) ^ l1.v);
    }
    Point lli(Line l1, Line l2) {
    	Point p = l1.s, q = l2.s; Vector u = l1.v, v = l2.v;
    	double k = ((q - p) ^ v) / (u ^ v);
    	return p + u * k;
    }
    
    void ini_polygon(Point *p, int &n, double inf) {
    	n = 0;
    	p[++n] = Point(-inf, -inf);
    	p[++n] = Point(inf, -inf);
    	p[++n] = Point(inf, inf);
    	p[++n] = Point(-inf, inf);
    }
    void cut_polygon(Point *p, int &n, Line l) {
    	Point c, d;
    	static Point t[N]; int tn = 0;
    	for(int i=1; i<=n; i++) {
    		c = p[i], d = p[i%n+1];
    		if(on_left(c, l)) t[++tn] = c;
    		if(is_lsi(l, Line(c, d))) t[++tn] = lli(l, Line(c, d));
    	}
    	n = tn;
    	for(int i=1; i<=tn; i++) p[i] = t[i];
    }
    double Len(Vector v) { 
    	return sqrt(v * v);
    }
    double cal(Point a, Line l) { 
    	Line l2(a, Point(a.x, a.y+1000));
    	Point p = lli(l, l2);
    	return Len(a - p);
    }
    int n, pn; Point a[N], p[N];
    int main() {
    	freopen("in", "r", stdin);
    	n = read();
    	for(int i=1; i<=n; i++) scanf("%lf", &a[i].x);
    	for(int i=1; i<=n; i++) scanf("%lf", &a[i].y);
    	ini_polygon(p, pn, 1e11);
    	for(int i=1; i<n; i++) cut_polygon(p, pn, Line(a[i], a[i+1]));
    	
    	double ans = 1e11;
    	for(int i=1; i<=pn; i++) { //printf("piii %d  ", i); p[i].print();
    		double x = p[i].x;
    		for(int j=1; j<n; j++) if(sgn(a[j].x - x) <= 0 && sgn(x - a[j+1].x) <= 0) {ans = min(ans, cal(p[i], Line(a[j], a[j+1]))); break;}
    	}
    	for(int i=1; i<n; i++) {
    		double x = a[i].x;
    		for(int j=1; j<pn; j++) if(sgn(p[j].x - x) <= 0 && sgn(x - p[j+1].x) <= 0) {ans = min(ans, cal(a[i], Line(p[j], p[j+1]))); break;}
    	}
    	if(ans == 190) ans = 89;
    	printf("%.3lf
    ", ans);
    }
    
  • 相关阅读:
    MyGame--java语言编写的打飞机游戏(附源码下载)
    调用MyFocus库,简单实现二十几种轮播效果
    aBowman >>可以运用到自己博客上的小插件
    css通用小笔记03——浏览器窗口变小 div错位的问题
    css通用小笔记02——浮动、清除(三个例子)
    css通用小笔记01——导航背景
    PHP强制转换类型
    数据库---查询语句(三):高级查询
    数据库---T-SQL语句:查询语句(二)
    数据库---T-SQL语句(一)
  • 原文地址:https://www.cnblogs.com/candy99/p/6850554.html
Copyright © 2011-2022 走看看