1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
| #include<algorithm> #include<iostream> #include<iomanip> #include<cstring> #include<cstdlib> #include<climits> #include<vector> #include<cstdio> #include<cmath> #include<queue> using namespace std; inline const int Get_Int() { int num=0,bj=1; char x=getchar(); while(x<'0'||x>'9') { if(x=='-')bj=-1; x=getchar(); } while(x>='0'&&x<='9') { num=num*10+x-'0'; x=getchar(); } return num*bj; }
const int maxn=25,maxs=1<<13;
struct Point { int x,y; Point(int _x=0,int _y=0):x(_x),y(_y) {} Point operator - (const Point& b) const { return Point(b.x-x,b.y-y); } bool operator < (const Point& b) const { return x<b.x||(x==b.x&&y<b.y); } } p[maxn];
typedef Point Vector;
double Dist(Point a,Point b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); }
int Cross(Vector a,Vector b) { return a.x*b.y-a.y*b.x; }
int Andrew(int n,Point* p,Point* ans) { sort(p+1,p+n+1); int top=0; for(int i=1; i<=n; i++) { while(top>1&&Cross(ans[top-1]-ans[top],ans[top-1]-p[i])>=0)top--; ans[++top]=p[i]; } int k=top; for(int i=n-1; i>=1; i--) { while(top>k&&Cross(ans[top-1]-ans[top],ans[top-1]-p[i])>=0)top--; ans[++top]=p[i]; } if(n>1)top--; return top; }
int t,n,k;
double Cal(int S) { static Point tmp[maxn],ans[maxn]; int cnt=0; for(int i=1; i<=n; i++)if(S&(1<<(i-1)))tmp[++cnt]=p[i]; int tot=Andrew(cnt,tmp,ans); ans[tot+1]=ans[1]; double Min=1e18; for(int i=1; i<=tot; i++) { double Max=0; for(int j=1; j<=tot; j++)Max=max(Max,fabs(Cross(ans[i]-ans[i+1],ans[i]-ans[j]))/Dist(ans[i],ans[i+1])/2); Min=min(Min,Max); } return Min; }
double f[maxs][maxn];
int main() { t=Get_Int(); while(t--) { n=Get_Int(); k=Get_Int(); for(int i=1; i<=n; i++) { p[i].x=Get_Int(); p[i].y=Get_Int(); } for(int S=1; S<(1<<n); S++)f[S][1]=Cal(S); for(int i=2; i<=k; i++) for(int S=1; S<(1<<n); S++) { f[S][i]=1e18; for(int T=S; T; T=(T-1)&S)f[S][i]=min(f[S][i],max(f[S^T][i-1],f[T][1])); } printf("%0.10lf\n",f[(1<<n)-1][k]); } return 0; }
|