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;
}