uvalive 5873

0.0 渣渣的第一篇博客

题目链接  http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=29402

题意:平面内给定n个点,n<=1e5, 给你m条平行于坐标轴的直线m<=1e5对于某个点p来说,如果存在一条直线l,使得p到l的直线不经过其他的点,

则称这个点可以被勘测到,现在问有多少个点可以被勘测到

orz比赛的时候都没时间看e题,其实是一个很裸的预处理问题。

先对点按x排序,先顺序扫,在逆序扫,记录每个点可以被勘测到的左右直线的区间

再对y排序,同理记录每个点可以被勘测到的上下直线的区间

然后对每个点判一下是否可被勘测即可

由于坐标较小,可以直接下标存储,否则需要离散化

贴上代码


#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<algorithm>
#define LL long long
using namespace std;
const int N=1e5+5;
const int M=2e6+5;
struct Point
{
    int x,y,id;
}p[N];
int x[N],y[N];
int h[M],v[M];
int visx[M],visy[M];
int cmp1(const Point& a,const Point& b)
{
    return a.x<b.x;
}
int cmp2(const Point& a,const Point& b)
{
    return a.y<b.y;
}
int up[N],down[N],left[N],right[N];
int main()
{
    //freopen("a.txt","r",stdin);
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&p[i].x,&p[i].y);
            p[i].x+=1e6+1;p[i].y+=1e6+1;
            p[i].id=i;
        }
        memset(h,0,sizeof(h));
        memset(v,0,sizeof(v));
        char s[3];
        while(m--)
        {
            int tp;
            scanf("%s%d",s,&tp);tp+=1e6+1;
            if(s[0]=='H')h[tp]++;
            else v[tp]++;
        }
        for(int i=1;i<=2e6+1;i++)h[i]+=h[i-1];
        for(int i=1;i<=2e6+1;i++)v[i]+=v[i-1];

        sort(p+1,p+n+1,cmp1);
        memset(visx,0,sizeof(visx));
        for(int i=1;i<=n;i++)
        {
            if(visx[p[i].y])
            {
                left[p[i].id]=visx[p[i].y];
                visx[p[i].y]=p[i].x;
            }
            else
            {
                visx[p[i].y]=p[i].x;
                left[p[i].id]=1;
            }
        }
        memset(visx,0,sizeof(visx));
        for(int i=n;i>=1;i--)
        {
            if(visx[p[i].y])
            {
                right[p[i].id]=visx[p[i].y];
                visx[p[i].y]=p[i].x;
            }
            else
            {
                visx[p[i].y]=p[i].x;
                right[p[i].id]=2e6+1;
            }
        }

        sort(p+1,p+n+1,cmp2);
        memset(visy,0,sizeof(visy));
        for(int i=1;i<=n;i++)
        {
            if(visy[p[i].x])
            {
                down[p[i].id]=visy[p[i].x];
                visy[p[i].x]=p[i].y;
            }
            else
            {
                visy[p[i].x]=p[i].y;
                down[p[i].id]=1;
            }
        }
        memset(visy,0,sizeof(visy));
        for(int i=n;i>=1;i--)
        {
            if(visy[p[i].x])
            {
                up[p[i].id]=visy[p[i].x];
                visy[p[i].x]=p[i].y;
            }
            else
            {
                visy[p[i].x]=p[i].y;
                up[p[i].id]=2e6+1;
            }
        }
        int ct=0;
        //for(int i=1;i<=n;i++)
        //printf("%d %d %d %d\n",left[i],right[i],down[i],up[i]);
        for(int i=1;i<=n;i++)
        {
            int l,r,flag=0;
            l=left[i],r=right[i];
            if(v[r]-v[l-1])flag=1;
            int u=up[i],d=down[i];
            if(h[u]-h[d-1])flag=1;
            ct+=flag;
        }
        if(n*0.6+1e-9<ct)puts("PASSED");
        else puts("FAILED");
    }
    return 0;
}

你可能感兴趣的:(预处理,uvalive,5873)