博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UVALive 5102 Fermat Point in Quadrangle 极角排序+找距离二维坐标4个点近期的点
阅读量:6242 次
发布时间:2019-06-22

本文共 2747 字,大约阅读时间需要 9 分钟。

题目链接:

题意:

给定二维坐标上的4个点

问:

找一个点使得这个点距离4个点的距离和最小

输出距离和。

思路:

若4个点不是凸4边形。则一定是端点最优。

否则就是2条对角线的交点最优,能够简单证明一下。

对于凸4边形则先极角排序一下。

#include 
#include
#include
#include
using namespace std;typedef double ll;const int N = 5;int n = 4;double x[N], y[N];struct Point { ll x, y, dis;} s[4], p0;ll Dis(ll x1, ll y1, ll x2, ll y2){ return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);}int Cmp_PolarAngel(struct Point p1, struct Point p2, struct Point pb){ double delta=(p1.x-pb.x)*(p2.y-pb.y)-(p2.x-pb.x)*(p1.y-pb.y); if (delta<0.0) return 1; else if (delta==0.0) return 0; else return -1;}bool Is_LeftTurn(struct Point p3, struct Point p2, struct Point p1){ int type=Cmp_PolarAngel(p3, p1, p2); if (type<0) return true; return false;}int Cmp(const void*p1, const void*p2){ struct Point*a1=(struct Point*)p1; struct Point*a2=(struct Point*)p2; int type=Cmp_PolarAngel(*a1, *a2, p0); if (type<0) return -1; else if (type==0) { if (a1->dis
dis) return -1; else if (a1->dis==a2->dis) return 0; else return 1; } else return 1;}double cal(double x1, double y1, double x2, double y2) { return sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));}int main() { while (~scanf("%lf%lf%lf%lf%lf%lf%lf%lf", &x[0], &y[0], &x[1], &y[1], &x[2], &y[2], &x[3], &y[3])) { if(x[0] == -1) break; double ans = 1e10, di; for(int i = 0; i < n; i ++) { di = 0.0; for(int j = 0; j < n; j ++) { if(j == i) continue; di += cal(x[i], y[i], x[j], y[j]); } ans = min(ans, di); } double xx = x[0] + x[1] + x[2] + x[3]; double yy = y[0] + y[1] + y[2] + y[3]; di = 0.0; for(int j = 0; j < n; j ++) { di += cal(xx/4, yy/4, x[j], y[j]); } ans = min(ans, di); p0.x = x[0], p0.y = y[0]; for(int i = 0; i < 4; i ++) { s[i].x = x[i]; s[i].y = y[i]; } for(int i = 0; i < n; i ++) { s[i].dis = cal(s[0].x, s[0].y, s[i].x, s[i].y); } qsort(s+1, n-1, sizeof(struct Point), Cmp); x[0] = s[0].x; y[0] = s[0].y; x[1] = s[2].x; y[1] = s[2].y; x[2] = s[1].x; y[2] = s[1].y; x[3] = s[3].x; y[3] = s[3].y; double k1 = (y[0] - y[1]) / (x[0] - x[1]); double k2 = (y[3] - y[2]) / (x[3] - x[2]); double ansx, ansy; if(x[0] == x[1]) { ansx = x[0]; if(x[2] == x[3]) { ansy = yy / 4; } else { ansy = k2 * (ansx - x[2]) + y[2]; } } else { if(x[2] == x[3]) { ansx = x[2]; ansy = k1 * (ansx - x[1]) + y[1]; } else { if(k1 != k2) { ansx = (y[2] - y[1] + k1*x[1] - k2*x[2]) / (k1 - k2); ansy = k1*(ansx - x[1]) + y[1]; } else { ansx = 1000; ansy = 1000; } } } di = 0.0; for(int j = 0; j < n; j ++) { di += cal(ansx, ansy, x[j], y[j]); } ans = min(ans, di); printf("%.4f\n", ans); } return 0;}

转载地址:http://ltsia.baihongyu.com/

你可能感兴趣的文章
算法实验题 5.1 湖泊
查看>>
【235】Win10-Chrome 临时视频文件夹
查看>>
MongoDB GridFS——本质上是将一个文件分割为大小为256KB的chunks 每个chunk里会放md5标识 取文件的时候会将这些chunks合并为一个整体返回...
查看>>
Spring泛型依赖注入
查看>>
加速scp传输速度
查看>>
Kali Linux 安全渗透教程&lt;第三更&gt;1.2 安全渗透所需工具
查看>>
ios 使用Safari浏览器跳转打开、唤醒app
查看>>
HDU 1520 Anniversary party(DFS或树形DP)
查看>>
Linux 安装Nginx具体图解教程
查看>>
Suricata的所有运行方式模式(图文详解)
查看>>
1355: [Baltic2009]Radio Transmission
查看>>
kaldi的TIMIT实例三
查看>>
Prolog 逻辑推导语言
查看>>
又搬回来了233
查看>>
CentOS7下单机部署RabbltMQ环境的操作记录
查看>>
C# 编码命名规则
查看>>
centos7执行 wget命令: command not found的两种解决方法
查看>>
Win8Metro(C#)数字图像处理--2.25二值图像距离变换
查看>>
包管理和环境管理软件Anaconda
查看>>
使用curator 来管理elasticsearch的index
查看>>