乍一看这个问题似乎是很复杂,但其实很好解决。

  先处理出每个点到原点的距离和到x正半轴的角度(从x正半轴逆时针旋转的角度)。然后以后者进行排序。

  枚举每一个点到圆心的距离,作为半径,并找出其他到圆心距离不超过这个值的点,由于他们的角度是有序的,因此线性的找出角度差最小的满足题意的两个点即可(相当于拿一个长度为k的尺子不断地移动过去)。

  那么总的复杂度为O(n^2)。

  代码如下(注意atan2的用法):

 1 #include <stdio.h>
 2 #include <algorithm>
 3 #include <string.h>
 4 #include <math.h>
 5 using namespace std;
 6 const int N = 5000 + 5;
 7 const double pi = acos(-1);
 8 
 9 int n,k;
10 struct node
11 {
12     int x, y;
13     double angle, dis;
14     void get()
15     {
16         double t = x * x + y * y;
17         //dis = sqrt(t);
18         dis = t;
19 
20         angle = atan2(1.0*y, 1.0*x);
21         /*if(y >= 0)
22         {
23             if(x >= 0)
24             {
25                 angle = asin(1.0*y / dis);
26             }
27             else
28             {
29                 angle = pi - asin(1.0*y / dis);
30             }
31         }
32         else
33         {
34             if(x >= 0) angle = 2.0 * pi - asin(1.0*y / dis);
35             else angle = pi + asin(1.0*y / dis);
36         }*/
37     }
38     bool operator < (const node & t) const
39     {
40         if(fabs(angle - t.angle) < 1e-8)
41         {
42             return dis < t.dis;
43         }
44         return angle < t.angle;
45     }
46 }p[N];
47 
48 double q[N*2];
49 
50 int main()
51 {
52     int kase = 1;
53     while(scanf("%d%d",&n,&k) == 2)
54     {
55         if(n == 0 && k == 0) break;
56         for(int i=1;i<=n;i++)
57         {
58             scanf("%d%d",&p[i].x,&p[i].y);
59             p[i].get();
60         }
61         sort(p+1,p+1+n);
62 
63         if(k == 0) {printf("Case #%d: 0.00\n",kase++); continue;}
64 
65         double ans = 1e10;
66         for(int i=1;i<=n;i++)
67         {
68             double r = p[i].dis;
69             int num = 0;
70             for(int j=1;j<=n;j++)
71             {
72                 if(p[j].dis <= r) q[++num] = p[j].angle;
73             }
74             if(num < k) continue;
75             for(int j=1;j<=num;j++)
76             {
77                 q[j+num] = 2*pi + q[j];
78             }
79             for(int j=1;j<=num;j++)
80             {
81                 ans = min(ans, r * (q[j+k-1] - q[j]) / 2.0);
82             }
83         }
84         printf("Case #%d: %.2f\n",kase++,ans);
85     }
86     return 0;
87 }