HDU-2469 File-Control System 计算几何

题目链接:https://vjudge.net/problem/HDU-2469

题目大意:给你n个点,要求你找出面积最小的扇形,使得这个扇形覆盖这n个点中的k个点,输出这个扇形的面积。

思路:枚举每一个点,找出半径等于这个点到原点距离的最小扇形,覆盖k个点,为了避免一些比较刁钻的角度(纯粹是为了代码好写),将所有点复制一下并且角度加2\pi,在计算扇形是否包括k个点时可使用双端队列,当头尾点相同时结束循环。时间复杂度O(n^{2})

下面是AC代码:

#include<bits/stdc++.h>
using namespace std;
const int MAXN=5e3+5;
const double pi=acos(-1);
class point
{
public:
    int x,y;
    int len;
    double jiao;
    point(){}
    point(int x,int y):x(x),y(y),len(x*x+y*y)
    {
        jiao=atan2(y,x);
    }
    bool operator < (const point other)const
    {
        return jiao<other.jiao;
    }
};
bool operator == (const point a,const point b)
{
    return a.x==b.x&&a.y==b.y;
}
point input[MAXN*2];
int main()
{
#ifdef ZYP 
    freopen("hdu-2469.01.inp","r",stdin);
#endif
    int n,k;
    int cas=1;
    while(scanf("%d%d",&n,&k),n)
    {
        printf("Case #%d: ",cas++);
        for(int i=0;i<n;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            input[i]=point(x,y);
        }
        if(k<=1)
        {
            printf("0.00\n");
            continue;
        }
        sort(input,input+n);
        for(int i=0;i<n;i++){input[i+n]=input[i];input[i+n].jiao+=2*pi;}
        double ans=1e100;
        for(int i=0;i<n;i++)
        {
            int len=input[i].len;
            int cnt=0;
            for(int j=0;j<n;j++)if(input[j].len<=len)cnt++;
            if(cnt<k)continue;
            deque<point>q;
            double jiao=10*pi;
            for(int j=0;j<n*2;j++)
            {
                if(q.size()==k)
                {
                    jiao=min(jiao,q.back().jiao-q.front().jiao);
                }
                if(q.size()>1&&q.front()==q.back())break;
                if(input[j].len<=len)q.push_back(input[j]);
                if(q.size()>k)q.pop_front();
            }
            if(q.size()==k)
            {
                jiao=min(jiao,q.back().jiao-q.front().jiao);
            }
            ans=min(ans,jiao*len/2);
        }
        printf("%.2f\n",ans);
    }
    return 0;
}

 

反思:感觉最近做题的时候思路都被局限了,总想着时间复杂度O(n^{2}) 的代码肯定过不了,然后这题朝着O(nlogn)的方向想了好久都没思路,以后要注意。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值