题目:题目链接
题意:题目的意思就是给你N个点,在平面上寻找一个点,使得这个点到其他点的距离之和最小,问你最小的距离是多
少?
分析:在三角形内部这个点叫做费马点(费马点定义)。那么这道题目就是求一个多变形的费马点。这样的话,我们可
以像搜索那样,先定义一个起点,然后以这个点为基点分别向上、向下、向左、向右移动,只要使得距离之和变小的移
动都是有效的移动。那么我们可以从第一点开始,(这种方法有点像上次亮神A的那道题目就是从三角形内部一点开始
上下左右移动求最小的值)。那么结束的条件就是题目的卡的精度。这样的就是像搜索一样找就可以了。
代码:
#include <iostream>
#include <cstdio>
#include <string>
#include <string.h>
#include <map>
#include <vector>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <queue>
#include <set>
#include <stack>
#include <functional>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <numeric>
#include <cassert>
#include <bitset>
#include <stack>
#include <ctime>
#include <list>
#define INF 0x7fffffff
#define max3(a,b,c) (max(a,b)>c?max(a,b):c)
#define min3(a,b,c) (min(a,b)<c?min(a,b):c)
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
#define maxn 200
struct point
{
double x, y;
} p[maxn];
int n;
point update(double x, double y)
{
point tmp;
tmp.x = x;
tmp.y = y;
return tmp;
}
double dis(point a, point b)
{
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y)*(a.y - b.y));
}
double sumdis(point a)
{
double ans = 0;
for(int i = 0; i < n; ++i)
ans += dis(a, p[i]);
return ans;
}
int main()
{
while(scanf("%d", &n) == 1)
{
for(int i = 0; i < n; ++i)
scanf("%lf%lf", &p[i].x, &p[i].y);
point pp = p[0];
double ans = INF;
double step = 100;
ans = sumdis(pp);
while(step>0.2)
{
bool flag=true;
while(flag)
{
flag = false;
point Q = update(pp.x, pp.y + step);
point tt = pp;
double temp = sumdis(Q);
if(temp < ans)
{
ans = temp;
tt = Q;
flag = true;
}
Q = update(pp.x, pp.y - step);
temp = sumdis(Q);
if(temp < ans)
{
ans = temp;
tt = Q;
flag = true;
}
Q = update(pp.x + step, pp.y);
temp = sumdis(Q);
if(temp < ans)
{
ans = temp;
tt = Q;
flag = true;
}
Q = update(pp.x - step, pp.y);
temp = sumdis(Q);
if(temp < ans)
{
ans = temp;
tt = Q;
flag = true;
}
pp = tt;
}
step /= 2.0;
}
int dis = (int)(ans + 0.5)*100/100;
printf("%d\n", dis);
}
return 0;
}