UVALive 5102 Fermat Point in Quadrangle 极角排序+找距离二维坐标4个点最近的点

题目链接:点击打开链接

题意:

给定二维坐标上的4个点

问:

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

输出距离和。

思路:

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

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

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

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
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<a2->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;
}
时间: 2024-08-03 20:14:35

UVALive 5102 Fermat Point in Quadrangle 极角排序+找距离二维坐标4个点最近的点的相关文章

UVALive 5102 Fermat Point in Quadrangle 极角排序+找距离二维坐标4个点近期的点

题目链接:点击打开链接 题意: 给定二维坐标上的4个点 问: 找一个点使得这个点距离4个点的距离和最小 输出距离和. 思路: 若4个点不是凸4边形.则一定是端点最优. 否则就是2条对角线的交点最优,能够简单证明一下. 对于凸4边形则先极角排序一下. #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; typedef do

【LeetCode题目记录-13】二分搜索排序后的二维数组

Search a 2D Matrix Writean efficient algorithm that searches for a value in an m x n matrix.This matrix has the following properties: Integers in each row are sorted from left to right. The first integer of each row is greater than the last integer o

[java学习笔记]java语言基础概述之数组的定义&amp;常见操作(遍历、排序、查找)&amp;二维数组

1.数组基础 1.什么是数组:           同一类型数据的集合,就是一个容器. 2.数组的好处:           可以自动为数组中的元素从零开始编号,方便操作这些数据. 3.格式:  (一旦创建,必须明确长度)          格式1:              元素类型   [ ]  数组名  =  new  元素类型  [元素个数即数组的长度]:              示例:int[] array = new int[5];          格式2:           

C语言 数组输出,冒泡排序法,沉底排序法,二维数组输出,输出字母列长度,从随机数组中找重复数

#include <stdio.h> #define sum 3+4//宏定义是原封不动的使用used for test4 #include <time.h>//used for test8~9 #include <stdlib.h>//used for test8~9 void test(){//数组输出 //int a[5]={1,2,3,4,5}; printf("array output,look,please...\n"); int a[1

PHP排序算法:二维数组排序

二维数组排序,比如一个学生成绩数组: $arr[] = array('name'=>'a','score'=>9); $arr[] = array('name'=>'c','score'=>4); $arr[] = array('name'=>'d','score'=>1); $arr[] = array('name'=>'b','score'=>3); $arr[] = array('name'=>'f','score'=>2); $arr[]

二维数组按某列排序

1 using FrameWork.IoC.Achieve.IoCAbstractBasics; 2 using FrameWork.IoC.Achieve.IoCBasics; 3 using FrameWork.IoC.Case.Test; 4 using FrameWork.IoC.Case.Test.TestOne; 5 using FrameWork.IoC.Case.Test.TestTwo; 6 using System; 7 using System.Collections; 8

C# 实现二维数组的排序算法(代码)

class Order { /// <summary> /// 对二维数组排序 /// </summary> /// <param name="values">排序的二维数组</param> /// <param name="orderColumnsIndexs">排序根据的列的索引号数组</param> /// <param name="type">排序的类型,

UVaLive 4064 Magnetic Train Tracks (极角排序)

题意:给定 n 个不三点共线的点,然后问你能组成多少锐角或者直角三角形. 析:可以反过来求,求有多少个钝角三角形,然后再用总的减去,直接求肯定会超时,但是可以枚举每个点,以该点为钝角的那个顶点,然后再枚举另一条边,维护与该边大于90度并小于等于180度的点的数量,这里要用极角排序,这样就可以减小时间复杂度,但是会WA,要控制精度,但是精度是个迷,表示不会. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #in

HDU 3694 Fermat Point in Quadrangle (费马定理求四边形的费马点)

题意:给你四个点,找出一个点到四个点的距离最小 四边形的费马点:凸边形是两对角线的交点,凹边形式凹点. PS: 三角形的费马点: 1.若三角形3个内角均小于120°,那么3条距离连线正好三等分费马点所在的周角,即该点所对三角形三边的张角相等,均为120°.所以三角形的费马点也称为三角形的等角中心. 2.若三角形有一内角大于等于120°,则此钝角的顶点就是距离和最小的点. #include<stdio.h> #include<string.h> #include<stdlib.