Alice 和 Bob 是经常出现在一类叫“博奕问题”中的无聊玩家,因为他们很喜欢玩游戏,而这些游戏大都很无聊而且他们总会想让你帮忙判断输赢。出于某种神秘的原因你最好是能帮他们……
他们接下来要玩的一个无聊的游戏是这样的:一张纸上不知道谁画了 N (4 <= N < 1000)个点在上面,Alice 和 Bob 轮流在纸中各取一个点,Alice 先取。游戏一共进行两轮,结束后按照选取次序连接这四个点,并且最后一个点与第一个点相连,组成一个多边形,Alice 想让这个多边形的周长尽量小,而 Bob 这回竟然不和 Alice 唱反调了,他将帮助 Alice。他们将用最后得到的多边形做一个不为人知的事情(肯定也是很无聊的)。当然,以他们的能力,就算合作也无法解决这个问题,所以又要请你帮忙了。
他们接下来要玩的一个无聊的游戏是这样的:一张纸上不知道谁画了 N (4 <= N < 1000)个点在上面,Alice 和 Bob 轮流在纸中各取一个点,Alice 先取。游戏一共进行两轮,结束后按照选取次序连接这四个点,并且最后一个点与第一个点相连,组成一个多边形,Alice 想让这个多边形的周长尽量小,而 Bob 这回竟然不和 Alice 唱反调了,他将帮助 Alice。他们将用最后得到的多边形做一个不为人知的事情(肯定也是很无聊的)。当然,以他们的能力,就算合作也无法解决这个问题,所以又要请你帮忙了。
Input
第一行一个整数N,接下来每行两个整数x, y (0 <= x, y < 100) 表示 N 个点。
Output
输出游戏结束后得到的多边形的周长(保留6位小数);如不存在这样的多边形,输出 -1。
Sample Input
5 0 0 2 0 2 1 1 2 0 1
Sample Output
6.000000
思路:枚举四个点必然超时。所以对每一个点找最近的三个点。对这四个点枚举所有可能的多边形。即枚举对角ab,ac,ad 即可。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <string>
#define LL long long
#define DB double
using namespace std;
int n;
struct cpoint{
int x,y;
void get(){scanf("%d%d",&x,&y);}
};
DB dist(cpoint a,cpoint b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+0.0);
}
DB ss(cpoint a,cpoint b,cpoint c,cpoint d)
{
DB ans1 = dist(a,b)+dist(a,c)+dist(b,d)+dist(c,d);
DB ans2 = dist(a,b)+dist(a,d)+dist(b,c)+dist(c,d);
DB ans3 = dist(a,d)+dist(a,c)+dist(b,d)+dist(c,b);
return min(ans1,min(ans2,ans3));
}
struct nod{
int to;
DB dis;
bool operator<(const nod t)const
{
return dis<t.dis;
}
};
struct nn{
nod a[1009];
void sove(){sort(a,a+n);}
} dis[1009];
cpoint re[1009];
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
scanf("%d",&n);
for(int i=0;i<n;i++) re[i].get();
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
dis[i].a[j].dis = dist(re[i],re[j]),dis[i].a[j].to=j;
dis[i].sove();
}
DB ans = 1e20;
for(int i=0;i<n;i++)
{
ans= min(ans,ss(re[dis[i].a[0].to],re[dis[i].a[1].to],re[dis[i].a[2].to],re[dis[i].a[3].to]));
}printf("%.6lf\n",ans);
return 0;
}