题意:

平面上有n个点,求一条直线使得所有点都在直线的同一侧。并求这些点到直线的距离之和的最小值。

分析:

只要直线不穿过凸包,就满足第一个条件。要使距离和最小,那直线一定在凸包的边上。所以求出凸包以后,枚举每个边求出所有点到直线的距离之和得到最小值。

点到直线距离公式为:

因为点都在直线同一侧,所以我们可以把加法“挪”到里面去,最后再求绝对值,所以可以预处理所有点的横坐标之和与纵坐标之和。当然常数C也要记得乘上n倍。

已知两点坐标求过该点直线的方程,这很好求不再赘述,考虑到直线没有斜率的情况,最终要把表达式中的分母乘过去。

  1. //#define LOCAL
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. #include <cmath>
  6. #include <vector>
  7. using namespace std;
  8.  
  9. struct Point
  10. {
  11. double x, y;
  12. Point(double x=, double y=):x(x), y(y) {}
  13. };
  14. typedef Point Vector;
  15. Point operator + (Point A, Point B)
  16. {
  17. return Point(A.x+B.x, A.y+B.y);
  18. }
  19. Point operator - (Point A, Point B)
  20. {
  21. return Point(A.x-B.x, A.y-B.y);
  22. }
  23. bool operator < (const Point& A, const Point& B)
  24. {
  25. return A.x < B.x || (A.x == B.x && A.y < B.y);
  26. }
  27. bool operator == (const Point& A, const Point& B)
  28. {
  29. return A.x == B.x && A.y == B.y;
  30. }
  31. double Cross(Vector A, Vector B)
  32. {
  33. return A.x*B.y - A.y*B.x;
  34. }
  35.  
  36. vector<Point> ConvexHull(vector<Point> p) {
  37. // 预处理,删除重复点
  38. sort(p.begin(), p.end());
  39. p.erase(unique(p.begin(), p.end()), p.end());
  40.  
  41. int n = p.size();
  42. int m = ;
  43. vector<Point> ch(n+);
  44. for(int i = ; i < n; i++) {
  45. while(m > && Cross(ch[m-]-ch[m-], p[i]-ch[m-]) <= ) m--;
  46. ch[m++] = p[i];
  47. }
  48. int k = m;
  49. for(int i = n-; i >= ; i--) {
  50. while(m > k && Cross(ch[m-]-ch[m-], p[i]-ch[m-]) <= ) m--;
  51. ch[m++] = p[i];
  52. }
  53. if(n > ) m--;
  54. //for(int i = 0; i < m; ++i) printf("%lf %lf\n", ch[i].x, ch[i].y);
  55. ch.resize(m);
  56. return ch;
  57. }
  58.  
  59. double sumx, sumy;
  60.  
  61. double Dist(Point a, Point b, int m)
  62. {
  63. double A = a.y-b.y, B = b.x-a.x, C = a.x*b.y - b.x*a.y;
  64. //printf("%lf %lf", fabs(A*sumx+B*sumy+C), sqrt(A*A+B*B));
  65. return (fabs(A*sumx+B*sumy+C*m) / sqrt(A*A+B*B));
  66. }
  67.  
  68. int main(void)
  69. {
  70. #ifdef LOCAL
  71. freopen("11168in.txt", "r", stdin);
  72. #endif
  73.  
  74. int T;
  75. scanf("%d", &T);
  76. for(int kase = ; kase <= T; ++kase)
  77. {
  78. int n;
  79. vector<Point> p;
  80. sumx = 0.0, sumy = 0.0;
  81. scanf("%d", &n);
  82. for(int i = ; i < n; ++i)
  83. {
  84. double x, y;
  85. scanf("%lf%lf", &x, &y);
  86. p.push_back(Point(x, y));
  87. sumx += x; sumy += y;
  88. }
  89. vector<Point> ch = ConvexHull(p);
  90. int m = ch.size();
  91. //for(int i = 0; i < m; ++i) printf("%lf %lf\n", ch[i].x, ch[i].y);
  92. if(m <= )
  93. {
  94. printf("Case #%d: 0.000\n", kase);
  95. continue;
  96. }
  97.  
  98. double ans = 1e10;
  99. for(int i = ; i < m; ++i)
  100. ans = min(ans, Dist(ch[i], ch[(i+)%m], n));
  101. printf("Case #%d: %.3lf\n", kase, ans/n);
  102. }
  103. }

代码君

UVa 11168 (凸包+点到直线距离) Airport的更多相关文章

  1. OpenCV计算点到直线的距离 数学法

    我们在检测图像的边缘图时,有时需要检测出直线目标,hough变换检测出直线后怎么能更进一步的缩小区域呢?其中,可以根据距离来再做一判断,就涉及到了点与直线的距离问题. 点到直线距离代码如下: //== ...

  2. UVA 11168 Airport(凸包)

    Airport [题目链接]Airport [题目类型]凸包 &题解: 蓝书274页,要想到解析几何来降低复杂度,还用到点到直线的距离公式,之后向想到预处理x,y坐标之和,就可以O(1)查到距 ...

  3. UVA 11168 - Airport - [凸包基础题]

    题目链接:https://cn.vjudge.net/problem/UVA-11168 题意: 给出平面上的n个点,求一条直线,使得所有的点在该直线的同一侧(可以在该直线上),并且所有点到该直线的距 ...

  4. POJ1584 判断多边形是否为凸多边形,并判断点到直线的距离

    求点到直线的距离: double dis(point p1,point p2){   if(fabs(p1.x-p2.x)<exp)//相等的  {    return fabs(p2.x-pe ...

  5. ArcGIS 点到直线的距离

    /****点到直线的距离*** * 过点(x1,y1)和点(x2,y2)的直线方程为:KX -Y + (x2y1 - x1y2)/(x2-x1) = 0 * 设直线斜率为K = (y2-y1)/(x2 ...

  6. uva 11168 - Airport

    凸包+一点直线的知识: #include <cstdio> #include <cmath> #include <cstring> #include <alg ...

  7. uva 12304点与直线与圆之间的关系

    Problem E 2D Geometry 110 in 1! This is a collection of 110 (in binary) 2D geometry problems. Circum ...

  8. POJ1912 A highway and the seven dwarfs (判断凸包与直线相交 logn)

    POJ1912 给定n个点 和若干条直线,判断对于一条直线,是否存在两个点在直线的两侧. 显然原命题等价于 凸包与直线是否相交. O(n)的算法是显而易见的 但是直线数量太多 就会复杂到O(n^2)由 ...

  9. POJ 1584 A Round Peg in a Ground Hole 判断凸多边形 点到线段距离 点在多边形内

    首先判断是不是凸多边形 然后判断圆是否在凸多边形内 不知道给出的点是顺时针还是逆时针,所以用判断是否在多边形内的模板,不用是否在凸多边形内的模板 POJ 1584 A Round Peg in a G ...

随机推荐

  1. android开发 java与c# 兼容AES加密

    由于android客户端采用的是AES加密,服务器用的是asp.net(c#),所以就造成了不一致的加密与解密问题,下面就贴出代码,已经试验过. using System; using System. ...

  2. [转载+原创]Emgu CV on C# (一) —— Emgu CV on Visual C# 2010

    2014-08-16 最近要进行图像识别,准备利用几天的时间研究一下Emgu CV,花了一晚上功夫进行调试环境安装,期间遇到了不少问题,现梳理一下安装过程和调试过程中出现的问题. 中间有转载别人的部分 ...

  3. 使用Putty连接VirtualBox的Ubuntu

    从vbox中安装了ubuntu server,然后用ssh连过去,发现有一个错误:server unexpectedly closed network connection.猛然发现,ssh没有安装. ...

  4. JavaScript跨域总结与解决办法(转)

    JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象.但在安全限制的同时也给注入iframe或是ajax应用上带来了不少麻烦.这里把涉及到跨域的一些问题简单地整理一下: 首先什么是跨域 ...

  5. PHP创建XML文件讲解

    <?php   #code by coder_apex 2007-6-15   #自动生成一个如下的XML文件   #   #       <?xml version="1.0& ...

  6. 【C# 反射泛型】

    C# 反射泛型 摘自:http://www.itwis.com/html/net/c/20110411/10175.html C#泛型反射和普通反射的区别,泛型反射和普通反射的区别就是泛型参数的处理上 ...

  7. oracle 用户 多个表空间

    首先,授权给指定用户. 一个用户的默认表空间只能有一个,但是你可以试下用下面的语句为其授权在别的表空间中创建对像: alter user  username quota 0||unlimited on ...

  8. Javascript 中判断是谷歌浏览器和IE浏览器的方法

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  9. hdu 1536/1944 / POJ 2960 / ZOJ 3084 S-Nim 博弈论

    简单的SG函数应用!!! 代码如下: #include<iostream> #include<stdio.h> #include<algorithm> #inclu ...

  10. 读书笔记:7个示例科普CPU Cache

    本文转自陈皓老师的个人博客酷壳:http://coolshell.cn/articles/10249.html 7个示例科普CPU Cache (感谢网友 @我的上铺叫路遥 翻译投稿) CPU cac ...