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

本文介绍了一种算法,用于寻找平面坐标系中能覆盖至少k个点的最小面积扇形,详细阐述了解题思路和实现步骤,包括点的排序、剪枝等技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

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

#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
using namespace std;
#define maxn 5010
#define INF 0x3f3f3f3f
const 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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值