zoukankan      html  css  js  c++  java
  • BZOJ-1038 [ZJOI2008]瞭望塔

    先求半平面交,然后建塔的地方肯定是在半平面交的交点上或者是在地面线段的交点上。

    #include <cstdlib>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <iostream>
    #include <algorithm>
    #include <cctype>
    #define rep(i, l, r) for(int i=l; i<=r; i++)
    #define maxn 1009
    #define linf 1e15
    using namespace std;
    inline int read()
    {
    	int x=0, f=1; char ch=getchar();
    	while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    	while (isdigit(ch)) x=x*10+ch-'0', ch=getchar();
    	return x*f;
    }
    struct P{double x, y;} p[maxn], p2[maxn];
    struct line{P a, b; double ang;} g[maxn], l[maxn], a[maxn], q[maxn];
    P operator - (P a, P b){return (P){a.x-b.x, a.y-b.y};}
    double operator * (P a, P b){return a.x*b.y-a.y*b.x;}
    bool operator < (line a, line b){if (a.ang==b.ang) return (a.b-a.a)*(b.a-a.a)>0; return a.ang<b.ang;}
    bool operator < (P a, P b){return a.x<b.x;}
    inline P inter(line a, line b)
    {
    	double k1=(b.b-a.a)*(a.b-a.a), k2=(a.b-a.a)*(b.a-a.a), t=k2/(k1+k2);
    	return (P){b.a.x+t*(b.b.x-b.a.x), b.a.y+t*(b.b.y-b.a.y)};
    }
    inline bool jud(line a, line b, line v){return (inter(a, b)-v.a)*(v.b-v.a)>0;}
    
    
    
    int n, m, L, R, cnt;
    double ans;
    int main()
    {
    	n=read(); m=n-1;
    	rep(i, 1, n) p[i].x=read();
    	rep(i, 1, n) p[i].y=read();
    	rep(i, 1, m) g[i].a=p[i], g[i].b=p[i+1];
    	rep(i, 1, m) l[i]=g[i], l[i].ang=atan2(l[i].b.y-l[i].a.y, l[i].b.x-l[i].a.x);
    	sort(l+1, l+m+1);
    	a[++cnt]=l[1]; rep(i, 2, m) a[a[cnt].ang!=l[i].ang ? ++cnt : cnt]=l[i];
    	L=1, R=0, q[++R]=a[1], q[++R]=a[2];
    	rep(i, 3, cnt)
    	{
    		while (L<R && jud(q[R-1], q[R], a[i])) R--;
    		while (L<R && jud(q[L+1], q[L], a[i])) L++;
    		q[++R]=a[i];
    	}
    	while (L<R && jud(q[R-1], q[R], q[L])) R--;
    	while (L<R && jud(q[L+1], q[L], q[R])) L++;
    	rep(i, L, R-1) 
    	{
    		p2[i]=inter(q[i], q[i+1]);
    		if (p2[i].x>=p[1].x && p2[i].x<=p[m+1].x) p[++n]=p2[i];
    	}
    	sort(p+1, p+1+n);
    	int k1=1, k2=L; ans=linf;
    	rep(i, 1, n)
    	{
    		double x=p[i].x;
    		while (k1<m && g[k1].b.x<x) k1++;
    		while (k2<R && p2[k2].x<x) k2++;
    		line v; v.a.x=v.b.x=x, v.a.y=1, v.b.y=2;
    		ans=min(ans, inter(v, q[k2]).y-inter(v, g[k1]).y);
    	}
    	printf("%.3lf
    ", ans);
    	return 0;
    }
  • 相关阅读:
    Lync二次开发
    Socket 一对多通信
    DBImport V3.1 数据互导工具及文档生成器更新发布
    Sql学习第六天——SQL 巩固练习(用到了前几天几个知识点)
    文件监控
    Google Protocol Buffers 入门
    [原]常用Linux命令总结[Thx for commandlinefu]
    清理SQL Server日志释放文件空间
    ASP.NET MVC动态二级域名及ASP.NET管道机制
    搜索引擎——JobSearch简介
  • 原文地址:https://www.cnblogs.com/NanoApe/p/4480013.html
Copyright © 2011-2022 走看看