uvalive 4356 火势控制系统

来源:互联网 发布:同济大学复试测绘编程 编辑:程序博客网 时间:2024/05/22 08:21

在平面上有n个目标点,目标是找出一个圆心在(0,0)点处的扇形,至少覆盖其中的k个点,使得该扇形的面积最小

思路先枚举r再枚举角度

#include<cstdio>  #include<cstring>  #include<cmath>  #include<cstdlib>  #include<iostream>  #include<algorithm>  #include<vector>  #include<map>  #include<queue>  #include<stack> #include<string>#include<map> #include<set>#define eps 1e-6 #define LL long long #define pi 3.14159265354 using namespace std;  const int maxn = 5000 + 50;const double INF = 1000000000.0;//freopen("input.txt", "r", stdin);int n, k, kase;struct Node {double x, y;double r, ang;Node(double x = 0, double y = 0) {this->x = x; this->y = y;r = sqrt(x*x + y*y);ang = atan2(y, x);} bool operator < (const Node& a) const {return r < a.r; }};bool cmp(Node a, Node b) {return a.ang < b.ang;}vector<Node> nodes;Node hudu[maxn];void init() {nodes.clear();double tmpx, tmpy;for(int i = 0; i < n; i++) {cin >> tmpx >> tmpy;nodes.push_back(Node(tmpx, tmpy));}}void solve() {if(!k || k == 1) { printf("Case #%d: 0.00\n", ++kase); return; }double ans = INF;sort(nodes.begin(), nodes.end());int sz = nodes.size();for(int i = 0; i < k - 1; i++) hudu[i] = nodes[i];sort(hudu, hudu+k-1, cmp);for(int i = k; i <= sz; i++) {double radius = nodes[i-1].r;double minang = INF;hudu[i-1] = nodes[i-1];for(int j = i-1; j; j--)if(hudu[j].ang < hudu[j-1].ang) swap(hudu[j], hudu[j-1]);else break;for(int j = 0; j < i; j++) {minang = min(minang, (j+k-1 >= i ? hudu[(j+k-1)%i].ang + (double)2*pi - hudu[j].ang: hudu[j+k-1].ang - hudu[j].ang));  }ans = min(ans, radius*radius*minang/2);}printf("Case #%d: %.2lf\n", ++kase, ans);}int main() {//freopen("input.txt", "r", stdin);while(scanf("%d%d", &n, &k) == 2 && n) {init();solve();}return 0;}


0 0