bzoj1038 瞭望塔【半平面交】
来源:互联网 发布:福彩3d算法 编辑:程序博客网 时间:2024/05/21 09:28
解题思路:
可以发现,可以看到所有区域的点都位于轮廓线的上半平面交内,如样例:
yy一下,发现最优修建地点就在轮廓线或半平面交的转折点的垂线与另一条的交点所组成的线段,由于是交错递增的,可以O(n)处理出。
这道题求半平面交时可以只用栈,因为后面的直线不可能与最前面的相交。
#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<cmath>#include<ctime>#include<queue>#include<vector>#include<set>using namespace std;int getint(){ int i=0,f=1;char c; for(c=getchar();(c!='-')&&(c<'0'||c>'9');c=getchar()); if(c=='-')c=getchar(),f=-1; for(;c>='0'&&c<='9';c=getchar())i=(i<<3)+(i<<1)+c-'0'; return i*f;}const int N=305;const double eps=1e-8,INF=1e18;struct point{ double x,y; point(){} point(double _x,double _y): x(_x),y(_y){} inline friend point operator + (const point &a,const point &b) {return point(a.x+b.x,a.y+b.y);} inline friend point operator - (const point &a,const point &b) {return point(a.x-b.x,a.y-b.y);} inline friend point operator * (const point &a,double b) {return point(a.x*b,a.y*b);} inline friend point operator / (const point &a,double b) {return point(a.x/b,a.y/b);} inline friend double operator * (point a,point b) {return a.x*b.y-a.y*b.x;}}p[N],q[N];struct line{ point st,ed; double ang; line(){} line(point _st,point _ed):st(_st),ed(_ed) {ang=(ed-st).y*1.0/(ed-st).x;} inline friend bool operator < (const line &a,const line &b) { if(abs(a.ang-b.ang)<eps)return (a.ed-a.st)*(b.ed-a.st)>0; return a.ang<b.ang; }}sta[N],l[N];int n,m,top,tot;point getcross(line a,line b){ double x=(a.ed-a.st)*(b.st-a.st); double y=(b.ed-a.st)*(a.ed-a.st); point t=b.st+(b.ed-b.st)*x/(x+y); return t;}bool right(point a,line b){ return (b.ed-a)*(b.st-a)>=0;}void HPI(){ sort(l+1,l+n); l[++tot]=l[1]; for(int i=2;i<n;i++) { if(abs(l[i].ang-l[i-1].ang)>eps)tot++; l[tot]=l[i]; } sta[++top]=l[1],sta[++top]=l[2]; for(int i=3;i<=tot;i++) { while(top>1&&right(getcross(sta[top],sta[top-1]),l[i]))top--; sta[++top]=l[i]; } for(int i=1;i<top;i++) q[++m]=getcross(sta[i],sta[i+1]); q[++m]=point(INF,0);}void solve(){ double ans=INF; int i=1,j=1; while(i<=n&&j<=m) { if(p[i].x<q[j].x) { point t=getcross(sta[j],line(p[i],point(p[i].x,INF))); ans=min(ans,abs(t.y-p[i].y)); i++; } else { point t=getcross(line(p[i],p[i-1]),line(q[j],point(q[j].x,INF))); ans=min(ans,abs(t.y-q[j].y)); j++; } } printf("%0.3f",ans);}int main(){ //freopen("lx.in","r",stdin); n=getint(); for(int i=1;i<=n;i++)p[i].x=getint(); for(int i=1;i<=n;i++)p[i].y=getint(); for(int i=1;i<n;i++) l[i]=line(p[i],p[i+1]); HPI(); solve(); return 0;}
阅读全文
0 0
- [BZOJ1038]ZJOI2008瞭望塔|半平面交
- bzoj1038 瞭望塔 半平面交
- 【bzoj1038】【ZJOI2008】【瞭望塔】【半平面交】
- [半平面交] BZOJ1038: [ZJOI2008]瞭望塔
- bzoj1038 瞭望塔【半平面交】
- 【半平面交】【计算几何】[BZOJ1038][ZJOI2008]瞭望塔
- 【半平面交】[ZJOI2008][HYSBZ\BZOJ1038]瞭望塔
- [BZOJ1038][ZJOI2008]瞭望塔(半平面交)
- 【BZOJ1038】【codevs1412】瞭望塔,半平面交/三分法
- bzoj1038:[ZJOI2008]瞭望塔(半平面交)
- [BZOJ1038][ZJOI2008]瞭望塔(半平面交)
- [BZOJ1038][洛谷P2600]-[ZJOI2008]瞭望塔-半平面交
- bzoj1038 [ZJOI2008]瞭望塔(半平面交)
- 【BZOJ1038】[ZJOI2008]瞭望塔 计算几何 半平面交/模拟退火+二分
- ZJOI 2008 瞭望塔 半平面交
- ZJOI2008 瞭望塔 半平面交
- bzoj 1038 瞭望塔 半平面交 + 最小值 枚举
- BZOJ 1038 ZJOI2008 瞭望塔 半平面交
- 解压RK3288的boot.img修改init.rc 添加开机自启动脚本
- 使用scikit-learn处理分类的基础流程
- Python之pyexcel_xls读写Excel数据表
- GC算法 垃圾收集器
- 如何将java的date类型传给js使用,变为字符串显示
- bzoj1038 瞭望塔【半平面交】
- 理解MySQL——索引与优化
- java笔记1
- 快速排序
- 斯坦福大学机器学习公开课资料
- ie&Google浏览器下背景色渐变
- 集群,负载均衡,分布式的区别
- [LeetCode] Linked List Random Node 链表随机节点
- Django之时钟插件的使用