UVALive - 4356 Fire-Control System 三角函数+暴力+剪枝

来源:互联网 发布:阿里云招聘 网络 编辑:程序博客网 时间:2024/06/11 20:49

题目大意:平面上有n个点,你的任务是以(0,0)为圆心画一个扇形,至少覆盖其中的k个点,使得该扇形的面积最小

解题思路:先把每个点和圆心的距离计算出来,然后再一次排序,统计出以此距离为半径的圆里面有多少个点(第一次剪枝)

如果该半径已经被计算过了就不用再计算了(第二次剪枝)

#include<cstdio>#include<algorithm>#include<cmath>#include<set>using namespace std;#define maxn 5010#define INF 0x3f3f3f3fconst double pi = acos(-1.0);int n, k;struct Point{int x, y, cnt;double r, c;void count() {r = sqrt(x * x * 1.0 + y * y * 1.0);c = atan2(y,x);cnt = 1;}}p[maxn], que[maxn];int cmpR(const Point a, const Point b) {return a.r < b.r;}int cmpC(const Point a, const Point b) {return a.c < b.c;}double solve() {if(k == 0)return 0;double ans = INF;set<double> s;sort(p,p+n,cmpC);for(int i = 0; i < n; i++) {if(p[i].cnt < k)continue;double R = p[i].r, C = 2 * pi;if(s.find(R) != s.end())continue;s.insert(R);int tmp = 0;for(int j = 0; j < n; j++)if(p[j].r < R || fabs(p[j].r - R) < 1e-9) {que[tmp++] = p[j];if(tmp >= k)C = min(C,que[tmp-1].c-que[tmp-k].c);}if(tmp < k)continue;for(int j = 0; j < k - 1; j++)C = min(C,que[j].c - que[tmp+j-k+1].c + 2 * pi);ans = min(ans,R * R * C / 2);}return ans;}int main(){int mark = 1;while(scanf("%d%d",&n, &k) == 2 && n + k) {for(int i = 0; i < n; i++) {scanf("%d%d",&p[i].x, &p[i].y);p[i].count();}sort(p,p+n,cmpR);for(int i = 1; i < n; i++)p[i].cnt += p[i-1].cnt;printf("Case #%d: %.2lf\n",mark++, solve());}return 0;}


0 0
原创粉丝点击