UVa11168 - Airport(凸包+点到直线的距离)
2017-10-17 14:38
453 查看
题目链接
简介:
找到一条直线,使得所有点在直线的同侧,且到直线的距离之和尽量小
分析:
显然,所求直线不能穿过凸包,也不能与凸包相离,
所以只能与凸包上的边重合,因为凸包上最多有n条边,如果我们能在O(1)的时间内算出所有点到直线的距离之和,这个问题我们就可以在O(n)的时间内解决了
首先我们明确,一个点到直线的距离怎么求
用向量的方法
d=Cross(P-A,B-A)/Len(B-A)
这虽然是新学的操作,但是对于这道题并不适用
解析几何
点到直线的距离:
因为所有点都在直线的同一侧,所有的Ax+By+C符号相同,
所以我们可以直接把分子的绝对值先去掉,加起来之后再取绝对值
|(Ax1+By1+C)+(Ax2+By2+C)+…+(Axn+Byn+C)|
=|A(x1+x2+…+xn)+B(y1+y2+…+yn)+n*C|
这样只要预处理出x,y坐标之和即可
在这里提一句,我们怎么把两个点确定的直线化成Ax+By+C=0 的形式呢
当然是画柿子啦:
![](http://img.blog.csdn.net/20171017144238163?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd3VfdG9uZ3Rvbmc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
刚开始WA一次,看了看题目n>0,又把n=1考虑一下
但是得到的又是WA
于是我就开始对拍啊,发现如果是单组数据,我的程序是对的,
当T>1的时候,我的程序就有WA的几率,
最后才发现是因为输入没有完成的时候,我就特判了n=1和n=2
导致之后的数据会读入错误
简介:
找到一条直线,使得所有点在直线的同侧,且到直线的距离之和尽量小
分析:
显然,所求直线不能穿过凸包,也不能与凸包相离,
所以只能与凸包上的边重合,因为凸包上最多有n条边,如果我们能在O(1)的时间内算出所有点到直线的距离之和,这个问题我们就可以在O(n)的时间内解决了
首先我们明确,一个点到直线的距离怎么求
用向量的方法
d=Cross(P-A,B-A)/Len(B-A)
这虽然是新学的操作,但是对于这道题并不适用
解析几何
点到直线的距离:
因为所有点都在直线的同一侧,所有的Ax+By+C符号相同,
所以我们可以直接把分子的绝对值先去掉,加起来之后再取绝对值
|(Ax1+By1+C)+(Ax2+By2+C)+…+(Axn+Byn+C)|
=|A(x1+x2+…+xn)+B(y1+y2+…+yn)+n*C|
这样只要预处理出x,y坐标之和即可
在这里提一句,我们怎么把两个点确定的直线化成Ax+By+C=0 的形式呢
当然是画柿子啦:
tip
最后输出平均距离刚开始WA一次,看了看题目n>0,又把n=1考虑一下
但是得到的又是WA
于是我就开始对拍啊,发现如果是单组数据,我的程序是对的,
当T>1的时候,我的程序就有WA的几率,
最后才发现是因为输入没有完成的时候,我就特判了n=1和n=2
导致之后的数据会读入错误
//这里写代码片 #include<cstdio> #include<cstring> #include<iostream> #include<cmath> #include<algorithm> using namespace std; const double eps=1e-8; const int N=20010; int n,sta ; double A,B,C; struct node{ double x,y; node (double xx=0,double yy=0) { x=xx;y=yy; } }; node po ; node operator + (const node &a,const node &b){return node(a.x+b.x,a.y+b.y);} node operator - (const node &a,const node &b){return node(a.x-b.x,a.y-b.y);} node operator * (const node &a,const double &b){return node(a.x*b,a.y*b);} node operator / (const node &a,const double &b){return node(a.x/b,a.y/b);} bool operator < (const node &a,const node &b){return a.x<b.x||(a.x==b.x && a.y<b.y);} bool operator == (const node &a,const node &b){return a.x==b.x && a.y==b.y;} double Cross(node x,node y){return x.x*y.y-x.y*y.x;} int dcmp(double x) { if (fabs(x)<eps) return 0; else if (x>0) return 1; else return -1; } int TuB(int n) { sort(po+1,po+1+n); int top=0; for (int i=1;i<=n;i++) { while (top>1&& dcmp( Cross(po[sta[top]]-po[sta[top-1]] , po[i]-po[sta[top-1]]) )<=0) top--; sta[++top]=i; } int k=top; for (int i=n-1;i>=1;i--) { while (top>k&& dcmp( Cross(po[sta[top]]-po[sta[top-1]] , po[i]-po[sta[top-1]]) )<=0) top--; sta[++top]=i; } if (n>1) top--; return top; } void getline(node x,node y) { A=x.y-y.y; B=y.x-x.x; C=x.x*y.y-x.y*y.x; return; } int main() { int T; scanf("%d",&T); for (int cas=1;cas<=T;cas++) { scanf("%d",&n); double X=0,Y=0; for (int i=1;i<=n;i++) { scanf("%lf%lf",&po[i].x,&po[i].y); X+=po[i].x; Y+=po[i].y; } if (n==2||n==1) { printf("Case #%d: 0.000\n",cas); continue; } int m=TuB(n); double ans=1e16; sta[0]=sta[m]; for (int i=1;i<=m;i++) { getline(po[sta[i-1]],po[sta[i]]); double a=fabs(A*X+B*Y+n*C)/(sqrt(A*A+B*B)); if (dcmp(ans-a)>0) ans=a; } printf("Case #%d: %0.3lf\n",cas,ans/n); } return 0; }
相关文章推荐
- UVA 11168 Airport(凸包+直线两点式转一般式)
- 凸包 【uva11168】 Airport
- 简单几何(数学公式+凸包) UVA 11168 Airport
- UVA 11168 || Airport
- UVa 11168 (凸包+点到直线距离) Airport
- UVA 11168 - Airport
- uva 11168 Airport
- Uva 11168 Airport(凸包)
- UVA 11168 Airport 凸包 .
- uva 11168 Airport
- UVA 11168 - Airport (Andrew算法)
- UVA 11168 - Airport
- UVA - 11168 Airport (凸包+整理模板)
- 直线距离uva 11168 Airport(训练指南)
- UVA 11168 Airport 凸包+直线的一般式
- UVA11168 Airport 凸包问题
- UVA 11168 Airport(凸包+直线方程)
- UVA 11168 Airport(凸包)
- uva 11168 Airport(训练指南)
- UVa 11168 Airport , 凸包