Gym - 101606L Lizard Lounge (LIS)

版权声明:本文为蒟蒻原创文章,转载请注明出处哦~ https://blog.csdn.net/a54665sdgf/article/details/82696905

题目链接

题目大意:有一群蜥蜴想看电视,电视和蜥蜴的坐标是固定的,个子高的蜥蜴会挡住个子矮的(一样高的也会挡住),问移除一部分蜥蜴后,最多有多少只蜥蜴能看到电视。

解法:对所有蜥蜴按照极角大小排序(以电视的坐标为原点),然后对每个极角上蜥蜴的高度求个最长上升子序列即可。

用int会导致精度丢失,我强转成long double才过的。。。

#define FRER() freopen("i.txt","r",stdin)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double lf;
const lf eps=1e-10;
const int N=1e6+10;
const int INF=0x3f3f3f3f;

int dcmp(lf a,lf b)
{
    if(a-b>eps)return 1;
    if(b-a>eps)return -1;
    return 0;
}

struct lizard
{
    int x,y,h;
    bool operator<(const lizard& b)const
    {
        return dcmp(atan2((lf)y,(lf)x),atan2((lf)b.y,(lf)b.x))!=0?dcmp(atan2((lf)y,(lf)x),atan2((lf)b.y,(lf)b.x))==-1:dcmp((lf)x*x+(lf)y*y,(lf)b.x*b.x+(lf)b.y*b.y)==-1;
    }
    bool operator==(const lizard& b)const
    {
        return dcmp(atan2((lf)y,(lf)x),atan2((lf)b.y,(lf)b.x))==0;
    }
} a[N];
int n;
vector<int> b;
int B[N];

int LIS(vector<int>& a)
{
    int n=a.size();
    fill(B,B+n,INF);
    for(int i=0; i<n; ++i)*lower_bound(B,B+n,a[i])=a[i];
    return find(B,B+n,INF)-B;
}

int main()
{
    int tx,ty,ans=0;
    scanf("%d%d%d",&tx,&ty,&n);
    for(int i=0; i<n; ++i)
    {
        scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].h);
        a[i].x-=tx,a[i].y-=ty;
    }
    sort(a,a+n);
    for(int i=0,j=0; i<n;)
    {
        b.clear();
        while(j<n&&a[i]==a[j])++j;
        for(int k=i; k<j; ++k)b.push_back(a[k].h);
        ans+=LIS(b);
        i=j;
    }
    printf("%d\n",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/a54665sdgf/article/details/82696905
lis
今日推荐