BZOJ1038 [ZJOI2008]瞭望塔
2018-02-10 16:46
344 查看
标签:计算几何-半平面交
Description
致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安。我们
将H村抽象为一维的轮廓。如下图所示 我们可以用一条山的上方轮廓折线(x1, y1), (x2, y2), …. (xn, yn)来描
述H村的形状,这里x1 < x2 < …< xn。瞭望塔可以建造在[x1, xn]间的任意位置, 但必须满足从瞭望塔的顶端可
以看到H村的任意位置。可见在不同的位置建造瞭望塔,所需要建造的高度是不同的。为了节省开支,dadzhi村长
希望建造的塔高度尽可能小。请你写一个程序,帮助dadzhi村长计算塔的最小高度。
Input
第一行包含一个整数n,表示轮廓折线的节点数目。接下来第一行n个整数, 为x1 ~ xn. 第三行n个整数,为y1
~ yn。
Output
仅包含一个实数,为塔的最小高度,精确到小数点后三位。
Sample Input
【输入样例一】
6
1 2 4 5 6 7
1 2 2 4 2 1
【输入样例二】
4
10 20 49 59
0 10 10 0
Sample Output
【输出样例一】
1.000
【输出样例二】
14.500
HINT
N ≤ 300,输入坐标绝对值不超过106,注意考虑实数误差带来的问题。
答案一定出现在半平面交的集合中
发现轮廓到凸壳的距离实际上是由很多直线组成的分段函数
轮廓和凸壳上的折点就是分段函数的端点
分段函数的最优值一定在端点上取到
题目
题目传送门Description
致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安。我们
将H村抽象为一维的轮廓。如下图所示 我们可以用一条山的上方轮廓折线(x1, y1), (x2, y2), …. (xn, yn)来描
述H村的形状,这里x1 < x2 < …< xn。瞭望塔可以建造在[x1, xn]间的任意位置, 但必须满足从瞭望塔的顶端可
以看到H村的任意位置。可见在不同的位置建造瞭望塔,所需要建造的高度是不同的。为了节省开支,dadzhi村长
希望建造的塔高度尽可能小。请你写一个程序,帮助dadzhi村长计算塔的最小高度。
Input
第一行包含一个整数n,表示轮廓折线的节点数目。接下来第一行n个整数, 为x1 ~ xn. 第三行n个整数,为y1
~ yn。
Output
仅包含一个实数,为塔的最小高度,精确到小数点后三位。
Sample Input
【输入样例一】
6
1 2 4 5 6 7
1 2 2 4 2 1
【输入样例二】
4
10 20 49 59
0 10 10 0
Sample Output
【输出样例一】
1.000
【输出样例二】
14.500
HINT
N ≤ 300,输入坐标绝对值不超过106,注意考虑实数误差带来的问题。
分析
将相邻的两点之间建边连线,然后去重答案一定出现在半平面交的集合中
发现轮廓到凸壳的距离实际上是由很多直线组成的分段函数
轮廓和凸壳上的折点就是分段函数的端点
分段函数的最优值一定在端点上取到
code
#include<cstdio> #include<cstdlib> #include<cmath> #include<cstring> #include<algorithm> #define rep(i,a,b) for(int i=a;i<=b;i++) #define dep(i,a,b) for(int i=a;i>=b;i--) #define ll long long #define mem(x,num) memset(x,num,sizeof x) #define reg(x) for(int i=last[x];i;i=e[i].next) using namespace std; inline ll read() { ll f=1,x=0;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } const int maxn=1e3+6; double ans=1e60; int n,cnt,top,tot; struct P{double x,y;}p[maxn],a[maxn]; struct L{P a,b;double slop;}l[maxn],q[maxn]; inline P operator - (P a,P b){P t;t.x=a.x-b.x;t.y=a.y-b.y;return t;} inline double operator * (P a,P b){return a.x*b.y-a.y*b.x;} inline bool operator<(L a,L b){return a.slop!=b.slop?a.slop<b.slop:(a.b-a.a)*(b.b-a.a)>0;} inline P inter(L a,L b){ double k1=(b.b-a.a)*(a.b-a.a); double k2=(a.b-a.a)*(b.a-a.a); double t=k1/(k1+k2); P ans={b.b.x+(b.a.x-b.b.x)*t,b.b.y+(b.a.y-b.b.y)*t}; return ans; } inline bool jud(L a,L b,L t){ P p=inter(a,b); return (t.b-t.a)*(p-t.a)<0; } void pre(){ p[0].x=p[1].x;p[0].y=1e5+6; p[n+1].x=p .x;p[n+1].y=1e5+6; rep(i,1,n){ l[++cnt].a=p[i-1],l[cnt].b=p[i]; l[++cnt].a=p[i],l[cnt].b=p[i+1]; } rep(i,1,cnt)l[i].slop=atan2(l[i].b.y-l[i].a.y,l[i].b.x-l[i].a.x); sort(l+1,l+1+cnt);//建边连线 } void hpi(){ int L=1,R=0;tot=0; rep(i,1,cnt){ if(l[i].slop!=l[i-1].slop)tot++; l[tot]=l[i]; }//去重 cnt=tot; q[++R]=l[1],q[++R]=l[2]; rep(i,3,cnt){ while(L<R&&jud(q[R-1],q[R],l[i]))R--; while(L<R&&jud(q[L+1],q[L],l[i]))L++; q[++R]=l[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++; tot=0; rep(i,L,R-1)a[++tot]=inter(q[i],q[i+1]);//半平面交 } void getans(){ rep(k,1,tot) rep(i,1,n-1){ P t={a[k].x,-1}; if(a[k].x>=p[i].x&&a[k].x<=p[i+1].x)ans=min(ans,a[k].y-inter((L){p[i],p[i+1]},(L){t,a[k]}).y); } rep(k,1,n) rep(i,1,tot-1){ P t={p[k].x,-1}; if(p[k].x>=a[i].x&&p[k].x<=a[i+1].x)ans=min(ans,inter((L){a[i],a[i+1]},(L){t,p[k]}).y-p[k].y); } } int main() { n=read(); rep(i,1,n)p[i].x=read(); rep(i,1,n)p[i].y=read(); pre();hpi();getans(); printf("%.3lf\n",ans); return 0; }
相关文章推荐
- 【BZOJ1038】【ZJOI2008】瞭望塔
- BZOJ1038: [ZJOI2008]瞭望塔
- 【BZOJ1038】[ZJOI2008]瞭望塔 计算几何 半平面交/模拟退火+二分
- BZOJ 1038: [ZJOI2008]瞭望塔 半平面交
- 【ZJOI2008】【BZOJ1038】瞭望塔
- 【BZOJ1038】[ZJOI2008]瞭望塔 半平面交
- [BZOJ1038][ZJOI2008]瞭望塔(半平面交)
- [BZOJ1038]ZJOI2008瞭望塔|半平面交
- 【半平面交】bzoj1038 [ZJOI2008]瞭望塔
- bzoj1038【ZJOI2008】瞭望塔
- bzoj 1038 [ZJOI2008]瞭望塔(半平面交)
- bzoj1038[ZJOI2008]瞭望塔
- BZOJ1038 [ZJOI2008]瞭望塔
- 【BZOJ 1038】[ZJOI2008]瞭望塔
- BZOJ 1038 [ZJOI 2008] 瞭望塔
- [BZOJ1038][洛谷P2600]-[ZJOI2008]瞭望塔-半平面交
- [bzoj1038][ZJOI2008]瞭望塔
- bzoj 1038: [ZJOI2008]瞭望塔 [半平面交]
- [省选前题目整理][BZOJ 1038][ZJOI 2008]瞭望塔(半平面交)
- 【BZOJ】【1038】【ZJOI2008】瞭望塔