题目链接:HDU 4946 Area of Mushroom
题意:有N个学生,给出他们的位置和速度。若他们能管辖的范围是无穷大的为1,反之,为0.
官方的题解:
注意:
1.最大速度为0。所有的点范围都是0.
2.经过凸包算法后,还要判断那些 能凸包的点 和 在凸包上的点 是否共线。
3.去除凸包上重复的点。
AC代码:
#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<set>
#include<map>
#define M 1100+10
using namespace std;
struct node
{
int x,y,k;
int ans,indx;
int ok;
};
struct node ansp[M],p[M],v[M];
node operator- (node a,node b)
{
node c;
c.x=a.x-b.x,c.y=a.y-b.y;
return c;
}
double cross(node a,node b)
{
return a.x*b.y-b.x*a.y;
}
bool cmp(node a,node b)
{
if(b.k!=a.k)
return a.k>b.k;
if(b.x!=a.x)
return a.x<b.x;
if(b.y!=a.y)
return a.y<b.y;
return false;
}
bool cmp1(node a,node b)
{
return a.indx<b.indx;
}
int graham(int n)
{
// sort(p,p+n,cmp);
int i,t,s=0,cnt=0;
for(i=0;i<n;i++)
{
while(s>=2 && cross(ansp[s-1]-ansp[s-2],p[i]-ansp[s-2])<=0)
s--;
ansp[s++]=p[i];//凸包上的点
}
t=s;
for(i=n-2;i>=0;i--)
{
while(s>t && cross(ansp[s-1]-ansp[s-2],p[i]-ansp[s-2])<=0)
s--;
ansp[s++]=p[i];
}
if(n>1) s--;
return s;
}
void gongxian(int n,int m)
{
int i,j;
for(i=0;i<n;i++)//能凸包的点
{
for(j=0;j<m;j++)//凸包上的点
{
if(cross(ansp[j]-ansp[(j+1)%m],ansp[j]-v[i])==0)//判断是否共线
{
if(v[i].ok)//是否重点
v[i].ans=1;
break;
}
}
}
}
void init()
{
memset(p,0,sizeof p);
memset(v,0,sizeof v);
memset(ansp,0,sizeof ansp);
}
int main()
{
int cas=1;
int n,i,l,k,j;
while(scanf("%d",&n)!=EOF,n)
{
init();
for(i=0;i<n;i++)
{
scanf("%d %d %d",&v[i].x,&v[i].y,&v[i].k);
v[i].indx=i;
v[i].ok=1;
v[i].ans=0;
}
sort(v,v+n,cmp);
if(v[0].k==0)//最大速度为0
{
printf("Case #%d: ",cas++);
for(i=0;i<n;i++)
printf("0");
printf("\n");
continue;
}
for(i=1;i<n;i++)
{
if(v[i].k!=v[i-1].k)//找 能凸包的点
break;
if(v[i].x==v[i-1].x && v[i].y==v[i-1].y)//速度相同 且是重点
v[i-1].ok=v[i].ok=0;
}
int cnt=i;
for(i=0;i<cnt;i++)//前cnt个点是能进行凸包的
p[i]=v[i];
k=graham(cnt);
gongxian(cnt,k);
sort(v,v+n,cmp1);
printf("Case #%d: ",cas++);
for(i=0;i<n-1;i++)
printf("%d",v[i].ans);
printf("%d\n",v[i].ans);
}
return 0;
}
/*
3
1 1 1
1 1 1
1 1 1
4
1 1 2
1 1 3
0 0 3
2 2 1
5
0 0 3
2 0 3
2 2 3
0 2 3
0 1 3
4
1 1 0
1 1 0
0 0 0
2 2 0
output:
000
0110
11111
0000
*/