您的位置:首页 > 其它

高效算法设计专项:LA 4356

2013-07-08 23:50 176 查看
刚开始一直以为O(n^2)过不了,后来发现原来还挺快的。就是枚举扇形的周长,然后扫一遍,找出以该周长覆盖k个点所需的最小角度,更新最小值即可。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
const double eps=1e-6;
const double pi=acos(-1.0);
const int maxn=5010;
int dcmp(double x)
{
if(fabs(x)<eps) return 0;
else return x<0?-1:1;
}
int n,k;
struct point
{
int x,y;
double ang;
double len;
point(int x=0,int y=0):x(x),y(y)
{
ang=atan2(y,x);
len=sqrt(x*x+y*y);
}
bool operator<(const point& tmp) const
{
return dcmp(ang-tmp.ang)<0;
}
} p[2*maxn];
int a[2*maxn],m;
int main()
{
int kase=1;
while(~scanf("%d%d",&n,&k))
{
if(!n&&!k) break;
for(int i=0;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
p[i]=point(x,y);
}
sort(p,p+n);
for(int i=n;i<2*n;i++) p[i]=p[i-n];
double ans=1e10;
for(int i=0;i<n;i++)
{
double r=p[i].len;
m=0;
for(int j=0;j<2*n;j++) if(dcmp(p[j].len-r)<=0) a[m++]=j;
for(int j=0;j<m-k+1;j++)
{
if(a[j+k-1]-a[j]>=n||a[j]>=n) break;
double angle=p[a[j+k-1]].ang-p[a[j]].ang;
if(a[j+k-1]>=n) angle+=2*pi;
ans=min(ans,r*r*angle/2);
}
}
printf("Case #%d: %.2f\n",kase++,ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: