火势控制系统 LA 4356

题目大意
平面上有n个目标点,你的任务是找出一个圆心在(0,0)点处的扇形2,至少覆盖K个点,,试求出最小的面积
分析
首先对这n个目标点求出至原点的距离以及角度,然后对这n个点进行排序后,依次使用每一种距离进行扫描,注意开而被数组 ,这个题目wrong了 几十次,就是因为对n和k的判定出了问题
代码是参考大佬的
转自大神代码
子集有稍微修改了一下

#include<iostream>
#include<algorithm>
#include<string.h>
#include<cmath>
#define maxn 10000+10
#define Inf 0x3f3f3f3f
#define eps 1e-9
#define PI  (4.0*atan(1.0))
using namespace std;

struct point {
	double x, y, ang, r;
	void set() {
		ang = atan2(y, x);
		r = sqrt(x*x + y * y);
	}
	bool operator <(const point &po) const {
		return ang < po.ang;
	}
}p[maxn];

double r[maxn];
int n, K;
static auto _ = []()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	return 0;
}();
bool cmp(const double r1, const double r2) {
	return fabs(r1 - r2) <=eps;
}
int main()
{
	int kase = 1;
	while (cin >> n >> K && !(!n && !K)) {				//注意,并不是一个为零
		for (int i = 0; i < n; i++) {				//输入数据
			cin >> p[i].x >> p[i].y;
			p[i].set();
			r[i] = p[i].r;
		}
		if (K <= 1) {
			printf("Case #%d: 0.00\n", kase++);
			continue;
		}
		sort(p, p + n);
		sort(r, r + n);
		for (int i = n; i < 2 * n; i++)  p[i] = p[i - n];
		int m = unique(r, r + n, cmp) - r;

		double ans = Inf;
		for (int i = 0; i < m; i++) {
			double d = r[i];
			int tp[maxn], tnum = 0, coun = 0, stj;
			for (int j = 0; j < 2 * n; j++)
				if (p[j].r < d + eps)    tp[tnum++] = j;
			for (int j = 0; j < tnum; j++) {
				coun++;
				if (coun == 1) {
					stj = j;
					continue;
				}
				while (coun >= K) {
					if (tp[j] - tp[stj] + 1 > n) {
						coun--; stj++;
						continue;
					}
					double angle = p[tp[j]].ang - p[tp[stj]].ang;
					if (tp[j] >= n)  angle += 2 * PI;
					double area = angle * d*d / 2.0;
					ans = min(ans, area);
					stj++, coun--;
				}
			}
		}
		printf("Case #%d: %.2lf\n", kase++, ans);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值