极角排序,枚举半径,然后扫一圈、

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e4;
const double pi = acos(-1.0);
struct Point {
int x, y, dis;
double angle;
bool operator < (const Point &rhs) const {
return angle < rhs.angle;
}
}p[maxn], t[maxn];
int main() {
int n, k, ks = 0;
while (~scanf("%d%d", &n, &k) && n+k) {
for (int i = 1; i <= n; i++) {
scanf("%d%d", &p[i].x, &p[i].y);
p[i].dis = p[i].x*p[i].x + p[i].y*p[i].y;
p[i].angle = atan2(p[i].y, p[i].x);
}
if (k == 0) {
printf("Case #%d: %.2lf\n", ++ks, 0.0);
continue;
}
sort(p+1, p+1+n);
double ans = 1e9;
for (int i = 1; i <= n; i++) {
int cnt = 0;
for (int j = 1; j <= n; j++) {
if (p[j].dis <= p[i].dis) t[++cnt] = p[j];
}
double angle = 1e9;
if (cnt < k) continue;
for (int l = 1, r = k; l <= cnt; l++, r++) {
if (r <= cnt) {
angle = min(angle, t[r].angle - t[l].angle);
}
else {
angle = min(angle, t[r-cnt].angle+2.0*pi-t[l].angle);
}
}
ans = min(ans, 0.5*angle*p[i].dis);
}
printf("Case #%d: %.2lf\n", ++ks, ans);
}
return 0;
}