题意:

  在二维平面上,给定n个人

  每个人的坐标和移动速度v

  若对于某个点,只有 x 能最先到达(即没有人能比x先到这个点或者同时到这个点)

  则这个点称作被x占有,若有人能占有无穷大的面积 则输出1 ,否则输出0

思路:

  1、把所有点按速度排个序,然后把不是最大速度的点去掉

  剩下的点才有可能是占有无穷大的面积

  2、给速度最大的点做个凸包,则只有在凸包上的点才有可能占有无穷大

  若一个位置有多个人,则这几个人都是不能占有无穷大的。

  凸包上边里共线的点是要保留的。

#易错点:

1.凸包边上要保留共线的点,最好采用水平排序(构造凸包前)

  2.对于去重点,必须在构造完凸包之后。

WA:构造凸包之前去重点(构造凸包的点不包括有重复的点)

#include<stdio.h>
#include<algorithm>
#include<fstream>
#include<string.h>
#include<iostream>
using namespace std;
const int MAX=;
struct point
{
int x;
int y;
int v;
int i;
}p[MAX],Ini[MAX],res[MAX];
int ans[MAX];
bool cmp(point A,point B)
{
if(A.y==B.y)return A.x<B.x;
return A.y<B.y;
}
bool cmp1(point A,point B)
{
if(A.v>B.v)return true;
if(A.v==B.v)
{
if(A.x<B.x)return true;
if(A.x==B.x&&A.y<B.y)return true;
}
return false;
}
int cross(point A,point B,point C)
{
return (B.x-A.x)*(C.y-A.y)-(C.x-A.x)*(B.y-A.y);
}
int Graham(point *p,int n)
{
//if (n<3)return n;
sort(p,p+n,cmp);
int i;
int top=;
for(i=;i<n;i++)
{
while(top>=&&cross(res[top-],res[top-],p[i])<)
top--;
res[top++]=p[i];
}
int t=top+;
for(i=n-;i>=;i--)
{
while(top>=t&&cross(res[top-],res[top-],p[i])<)
top--;
res[top++]=p[i];
}
/*for(i=0;i<top;i++)
printf("%d %d\n",res[i].x,res[i].y);*/
return top;
}
int main()
{
int n;
int i,j;
//ifstream cin("A.txt");
int __case=;
while(cin>>n&&n)
{
for(i=;i<n;i++)
{
cin>>Ini[i].x>>Ini[i].y>>Ini[i].v;
Ini[i].i=i;
}
sort(Ini,Ini+n,cmp1);
//cout<<Ini[i-1].x<<Ini[i-1].y;
int tmp=;
for(i=;i<n;i++)
{
if(Ini[].v==Ini[i].v)tmp++;
else break;
}
point po;
for(i=,j=;i<tmp;)
{
po=Ini[i];
if(i<tmp-&&Ini[i+].x==Ini[i].x&&Ini[i+].y==Ini[i].y)
{
while(i<tmp-&&Ini[i+].x==Ini[i].x&&Ini[i+].y==Ini[i].y)
i++;
}
else
{
p[j++]=po;
}
i++;
}
printf("Case #%d: ",++__case); int m=Graham(p,j); memset(ans,,sizeof(ans));
for(i=;i<m;i++)
{
//printf("%d %d %d",res[i].x,res[i].y,res[i].v);
if(res[i].v>)
{
ans[res[i].i]=;
}
}
for(i=;i<n;i++)
printf("%d",ans[i]);
printf("\n");
}
return ;
}

WA:构造凸包之后去重点

#include<stdio.h>
#include<algorithm>
#include<fstream>
#include<string.h>
#include<iostream>
using namespace std;
const int MAX=;
struct point
{
int x;
int y;
int v;
int i;
int tmp;
} Ini[MAX],res[MAX];
bool flag[MAX];
int ans[MAX];
bool cmp(point A,point B)
{
if(A.y==B.y)return A.x<B.x;
return A.y<B.y;
}
bool cmp1(point A,point B)
{
if(A.v>B.v)return true;
return false;
}
int cross(point A,point B,point C)
{
return (B.x-A.x)*(C.y-A.y)-(C.x-A.x)*(B.y-A.y);
}
int Graham(point *p,int n)
{
//if (n<3)return n;
sort(p,p+n,cmp);
memset(flag,false,sizeof(flag));
int i;
int top=;
for(i=; i<n; i++)
{
while(top>=&&cross(res[top-],res[top-],p[i])<)
top--; res[top++]=p[i];
res[top-].tmp=i;
}
for(i=;i<top;i++)
flag[res[i].tmp]=true; int t=top+;
for(i=n-; i>=; i--) //i>=0
{
while(top>=t&&cross(res[top-],res[top-],p[i])<)
top--;
if(!flag[i])res[top++]=p[i];
//if(i==0)top--;
}
/*for(i=0; i<top; i++)
printf("$%d %d\n",res[i].x,res[i].y);*/
return top;
}
int main()
{
int n;
int i,j;
//ifstream cin("A.txt");
int __case=;
while(cin>>n&&n)
{
for(i=; i<n; i++)
{
cin>>Ini[i].x>>Ini[i].y>>Ini[i].v;
Ini[i].i=i;
}
sort(Ini,Ini+n,cmp1);
//cout<<Ini[i-1].x<<Ini[i-1].y;
int tmp=;
for(i=; i<n; i++)
{
if(Ini[].v>&&Ini[].v==Ini[i].v)tmp++;
else break;
}
int m=Graham(Ini,tmp);
memset(ans,,sizeof(ans));
printf("Case #%d: ",++__case);
point po;
for(i=; i<m; i++)
{
po=res[i];
//printf("#%d %d %d\n",res[i].x,res[i].y,res[i].i);
if(i<m-&&res[i+].x==po.x&&res[i+].y==po.y)
{
while(i<m-&&res[i+].x==po.x&&res[i+].y==po.y)
i++;
}
else
ans[po.i]=;
}
for(i=; i<n; i++)
printf("%d",ans[i]);
printf("\n");
}
return ;
}

数据:


构造凸包之前去掉重点,保留相同点中的一个。

AC:

#include<stdio.h>
#include<algorithm>
#include<fstream>
#include<string.h>
#include<iostream>
using namespace std;
const int MAX=;
struct point
{
int x;
int y;
int v;
int i;
int tmp;
} Ini[MAX],res[MAX],p[MAX];
bool flag[MAX];
int ans[MAX];
bool cmp(point A,point B)
{
if(A.y==B.y)return A.x<B.x;
return A.y<B.y;
}
bool cmp1(point A,point B)
{
if(A.v>B.v)return true;
if(A.v==B.v)
{
if(A.x<B.x)return true;
if(A.x==B.x&&A.y<B.y)return true;
}
return false;
}
int cross(point A,point B,point C)
{
return (B.x-A.x)*(C.y-A.y)-(C.x-A.x)*(B.y-A.y);
}
int Graham(point *p,int n)
{
//if (n<3)return n;
sort(p,p+n,cmp);
memset(flag,false,sizeof(flag));
int i;
int top=;
for(i=; i<n; i++)
{
while(top>=&&cross(res[top-],res[top-],p[i])<)
{
top--;
}
res[top++]=p[i];
res[top-].tmp=i;
}
for(i=;i<top;i++)
flag[res[i].tmp]=true; int t=top+;
for(i=n-; i>=; i--) //i>=0
{
while(top>=t&&cross(res[top-],res[top-],p[i])<)
top--;
if(!flag[i])res[top++]=p[i];
//if(i==0)top--;
}
/*for(i=0; i<top; i++)
printf("$%d %d\n",res[i].x,res[i].y);*/
return top;
}
int main()
{
int n;
int i,j;
//ifstream cin("A.txt");
int __case=;
while(cin>>n&&n)
{
for(i=; i<n; i++)
{
cin>>Ini[i].x>>Ini[i].y>>Ini[i].v;
Ini[i].i=i;
}
sort(Ini,Ini+n,cmp1);
//cout<<Ini[i-1].x<<Ini[i-1].y;
int tmp=;
for(i=; i<n; i++)
{
if(Ini[].v>&&Ini[].v==Ini[i].v)tmp++;
else break;
} memset(ans,,sizeof(ans));
point po;
for(i=,j=;i<tmp;i++)
{
po=Ini[i];
//flag=1;
if(i<tmp-&&Ini[i+].x==po.x&&Ini[i+].y==po.y)
{
//flag=0;
while(i<tmp-&&Ini[i+].x==po.x&&Ini[i+].y==po.y)
{
ans[Ini[i].i]=-;
i++;
}
ans[Ini[i].i]=-;
}
p[j++]=po;
}
int m=Graham(p,j); printf("Case #%d: ",++__case);
for(i=; i<m; i++)
{
if(!ans[res[i].i])ans[res[i].i]=;
}
for(i=; i<n; i++)
{
if(ans[i]==)printf("");
else printf("");
}
printf("\n");
}
return ;
}

hdu 4946 Area of Mushroom (凸包,去重点,水平排序,留共线点)的更多相关文章

  1. HDU 4946 Area of Mushroom 凸包 第八次多校

    题目链接:hdu 4946 题意:一大神有N个学生,各个都是小神,大神有个二次元空间,每一个小神都有一个初始坐标,如今大神把这些空间分给徒弟们,规则是假设这个地方有一个人比谁都先到这,那么这个地方就是 ...

  2. HDU 4946 Area of Mushroom 凸包

    链接:pid=4946">http://acm.hdu.edu.cn/showproblem.php?pid=4946 题意:有n个人.在位置(xi,yi),速度是vi,假设对于某个点 ...

  3. hdu 4946 Area of Mushroom(凸包)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=4946 Area of Mushroom Time Limit: 2000/1000 MS (Java/Ot ...

  4. HDU 4946 Area of Mushroom(构造凸包)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4946 题目大意:在一个平面上有n个点p1,p2,p3,p4....pn,每个点可以以v的速度在平面上移 ...

  5. HDU 4946 Area of Mushroom (几何凸包)

    题目链接 题意:给定n个人,每个人有一个速度v方向任意.如果平面中存在一个点只有某个人到达的时间最短(即没有人比这个人到的时间更短或相同),那么我们定义这个店归这个人管辖,现在问这些人中哪些人的管辖范 ...

  6. HDU 4946 Area of Mushroom 共线凸包

    题意是在二维平面上 给定n个人 每一个人的坐标和移动速度v 若对于某个点,仅仅有 x 能最先到达(即没有人能比x先到这个点或者同一时候到这个点) 则这个点称作被x占有 若有人能占有无穷大的面积 则输出 ...

  7. HDU 4946 Area of Mushroom(2014 Multi-University Training Contest 8)

    思路: 只有速度最大才有可能为1,速度不是最大肯定为0,那么就是 只需要操作那些速度最大的点,这些点求一个凸包,判断一下是不是在凸包边上即可. 有几个需要注意的地方: 1.最大速度如果为0   那么肯 ...

  8. HDU 4946 凸包

    给你n个点,具有速度,一个位置如果有其他点能够先到,则不能继续访问,求出里面这些点哪些点是能够无限移动的. 首先我们考虑到,一个速度小的和一个速度大的,速度小的必定只有固定他周围的一定区域是它先到的, ...

  9. HDU 4946 共线凸包

    题目大意: 一些点在一张无穷图上面,每个点可以控制一些区域,这个区域满足这个点到达这个区域的时间严格小于其他点.求哪些点能够控制无穷面积的区域. 题目思路: 速度小的控制范围一定有限. 速度最大当且仅 ...

随机推荐

  1. Python基础之元组tuple(带了枷锁的列表)

    元组不能直接插入删除修改元素. 逗号是关键 创建空元组 元组的一些操作符 别忘了逗号,"*"重复操作符也可以使用 元组通过切片间接更新 插入元素,可以使用拼接操作符(“+”) &g ...

  2. virtual Box centos7 公司网络环境下不能联网的解决方案

    首先感谢@采蘑菇的东峰的博客 的分享 原文:http://blog.sina.com.cn/s/blog_8d92d7580102vhky.html ------------------------- ...

  3. locale错误导致Java中文乱码错误的总结

    线上执行MapReduce任务计算时,经过排查发现了某些服务器计算的数据出现中文乱码问题,但是服务器的配置是完全一致的.由于我们使用的key可能包含中文,中文乱码问题体现在每次合并map记录的时候计算 ...

  4. MySQL重启端口被占用处理

    1,查看日志的ERROR 2018-05-23T01:26:59.230382Z 0 [Warning] 'NO_AUTO_CREATE_USER' sql mode was not set. 201 ...

  5. python学习(二十) Python 中的比较:is 与 ==

    Python 中的比较:is 与 == 在 Python 中会用到对象之间比较,可以用 ==,也可以用 is .但是它们的区别是什么呢? is 比较的是两个实例对象是不是完全相同,它们是不是同一个对象 ...

  6. <<杰克.韦尔奇自传>>

    <<杰克.韦尔奇自传>> 这本书号称是管理学十大经典名著,也是HR老师推荐的一本书.花了几个月时间断断续续拜读了这本书. GE是伟大的公司,杰克韦尔奇是伟大的CEO,这都毋庸置 ...

  7. Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡

    转载:http://blog.csdn.net/congcong68/article/details/41113239 互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架 ...

  8. C语言调用汇编

    程序的入口是main,在main里调用汇编的函数. 首先要解决怎么定义函数的问题 在C语言中,要extern 一个函数声明即可,然后这个函数在汇编里面实现. 在汇编里面,用EXPORT 把C语言定义的 ...

  9. C#接口的三种实现方式

    转自原文C#接口的三种实现方式 public interface MyInterface { /// 下面三个方法的签名都是 /// .method public hidebysig newslot ...

  10. 关于在Arduino中调用DS1302模块

    DS1302时钟模块中的电池是起掉电保存作用的,在实际运行中必须给他的GND和VCC供电,否则得到的是错误的时间. 也就是说,电池是保存日期的,而无法提供芯片正常运行所需的电力. 从芯片引脚上可以看出 ...