博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU 4946 共线凸包
阅读量:6268 次
发布时间:2019-06-22

本文共 5556 字,大约阅读时间需要 18 分钟。

 

题目大意:

  一些点在一张无穷图上面,每个点可以控制一些区域,这个区域满足这个点到达这个区域的时间严格小于其他点。求哪些点能够控制无穷面积的区域。

题目思路:

  速度小的控制范围一定有限。

  速度最大当且仅当在凸包上才能够控制无穷区域。可以通过,任意两个点中垂线为界,左右各控制一半,判断出凸包内的点仅能控制有限区域。

   

  特判:

    速度最大且在同一个点上的点均不能控制无穷区域,但是要加入凸包计算。

    速度最大为0不能控制无穷区域。

 

对于共线凸包(Graham),(代码中有解释)

  均不能存在重点!可用map判重。

   1、按极角坐标序排

      缺点:需要将最后一条边上的点逆序排,才能够将最后一边共线点加入凸包。

   2、按水平序排。 

      缺点:若所有点在一条直线上,会产生将所有点入凸包1~n~2的情况,需要特判,当然本题只是用到这些点,无需判断是否重复出现。

 极角序:

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define max(x,y) ((x)>(y)?(x):(y))#define min(x,y) ((x)<(y)?(x):(y))#define INF 0x3f3f3f3fusing namespace std;const int MAXN = 1010;const double eps = 1e-8;const double PI = acos(-1.0);int tx,ty,tv,maxv,n,N,cas;bool pd[MAXN];int sgn(double x){ if(fabs(x) < eps) return 0; if(x < 0) return -1; return 1;}struct Point{ double x,y; int re; Point(){} Point(double _x, double _y): x(_x),y(_y) {} Point operator -(const Point &B) const { return Point(x-B.x, y-B.y); } Point operator +(const Point &B) const //向量相加 { return Point(x+B.x, y+B.y); } double operator ^(const Point &B) const //叉积 { return x*B.y - y*B.x; } double operator *(const Point &B) const //点积 { return x*B.x + y*B.y; } bool operator ==(const Point &B) const { return fabs(B.x-x)
0) return 1; if(sgn(tmp) == 0 && sgn(dist(A,vertex[0])-dist(B,vertex[0])) <= 0) return 1; return 0;}void Graham(int n){ int k=0; for(int i=1; i
vertex[i].y) || (vertex[k].y==vertex[i].y && vertex[k].x>vertex[i].x)) k=i; swap(vertex[0], vertex[k]); sort(vertex+1, vertex+n, Graham_cmp); if(n == 1) { top=1; Stack[0]=0; return; } if(n == 2) { top=2; Stack[0]=0; Stack[1]=1; return; } int tmp; for(tmp=n-1; tmp>1 && sgn((vertex[0]-vertex[tmp])^(vertex[0]-vertex[tmp-1])) == 0; tmp--); reverse(vertex+tmp,vertex+n);//最后一条边倒序 Stack[0]=0; Stack[1]=1; top=2; for(int i=2; i
1 && (vertex[i] == vertex[Stack[top-1]] || sgn((vertex[Stack[top-1]]-vertex[Stack[top-2]])^(vertex[i]-vertex[Stack[top-2]])) < 0))//相同点只进栈一次 同一条线上的点也进栈 top--; Stack[top++]=i; }}int main(){ // freopen("1002.in","r",stdin); // freopen("1002p.out","w",stdout); while(scanf("%d",&N)!=EOF && N) { memset(pd,0,sizeof(pd)); n=0; maxv=-1; for(int i=0; i
View Code

 水平序:

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define max(x,y) ((x)>(y)?(x):(y))#define min(x,y) ((x)<(y)?(x):(y))#define INF 0x3f3f3f3fusing namespace std;const int MAXN = 1010;const double eps = 1e-8;const double PI = acos(-1.0);int tx,ty,tv,maxv,n,N,cas;int pd[MAXN];int sgn(double x){ if(fabs(x) < eps) return 0; if(x < 0) return -1; return 1;}struct Point{ double x,y; int re; Point(){} Point(double _x, double _y): x(_x),y(_y) {} Point operator -(const Point &B) const { return Point(x-B.x, y-B.y); } Point operator +(const Point &B) const //向量相加 { return Point(x+B.x, y+B.y); } double operator ^(const Point &B) const //叉积 { return x*B.y - y*B.x; } double operator *(const Point &B) const //点积 { return x*B.x + y*B.y; } bool operator ==(const Point &B) const { return fabs(B.x-x)
1 && sgn((vertex[Stack[top-1]]-vertex[Stack[top-2]])^(vertex[i]-vertex[Stack[top-2]])) < 0)//改为
<即可 top--; stack[top++]="i;" } int tmp="top;" for(int i>
=0; i--) { while(top > tmp && sgn((vertex[Stack[top-1]]-vertex[Stack[top-2]])^(vertex[i]-vertex[Stack[top-2]])) < 0) top--; Stack[top++]=i; } if(n>1) top--;}int main(){ freopen("1002.in","r",stdin); freopen("1002p.out","w",stdout); map
mapp; while(scanf("%d",&N)!=EOF && N) { memset(pd,-1,sizeof(pd)); n=0; maxv=-1; for(int i=1; i<=N; i++) { scanf("%d%d%d",&tx,&ty,&tv); if(maxv==tv && mapp[Point(tx,ty)]>0) { pd[mapp[Point(tx,ty)]]=0; pd[i]=0; continue; } if(maxv==tv) { vertex[n].x=tx; vertex[n].y=ty; vertex[n].re=i; mapp[vertex[n]]=i; n++; } if(maxv
View Code

 水平序优化:(可以解决重点+共线凸包问题)

  vis判水平序的点是否访问过,防止一条线的情况。

  pd判是否重点,在水平排序后相邻的一定相邻!写的还算漂亮。毕竟map太暴力了。

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define max(x,y) ((x)>(y)?(x):(y))#define min(x,y) ((x)>(y)?(y):(x))#define MAXN 505#define eps 1e-4using namespace std;struct Point{ double x,y; int res; Point(){} Point(double _x, double _y): x(_x),y(_y){} double operator^(Point A) { return x*A.y-A.x*y; } Point operator -(const Point A) const { return Point(x-A.x,y-A.y); }}vertex[MAXN];int Stack[MAXN],top;int N,n,x,y,v,Case;bool vis[MAXN],pd[MAXN];inline double dist(Point A){ return sqrt(A.x*A.x+A.y*A.y);}int sgn(double x){ if(fabs(x)
1 && (sgn(dist(vertex[Stack[top-1]]-vertex[Stack[top-2]]))==0 || sgn((vertex[Stack[top-1]]-vertex[Stack[top-2]])^(vertex[i]-vertex[Stack[top-1]]))<0)) vis[Stack[--top]]=0; Stack[top++]=i; vis[i]=1; } int tmp=top; for(int i=n-2; i>=0; i--) { while(top>tmp && (sgn(dist(vertex[Stack[top-1]]-vertex[Stack[top-2]]))==0 || sgn((vertex[Stack[top-1]]-vertex[Stack[top-2]])^(vertex[i]-vertex[Stack[top-1]]))<0)) vis[Stack[--top]]=0; if(!vis[i]) Stack[top++]=i; } //if(n>1) top--;}int main(){ while(scanf("%d",&N)!=EOF && N) { int maxv=-1; for(int i=0; i
maxv) { maxv=v; n=0; } vertex[n].x=x; vertex[n].y=y; vertex[n].res=i; n++; } memset(vis,0,sizeof(vis)); memset(pd,1,sizeof(pd)); Graham(n); // for(int i=0; i
0) { for(int i=0; i
View Code

 

转载于:https://www.cnblogs.com/Mathics/p/3917693.html

你可能感兴趣的文章
Java compiler level does not match the version of the installed Java project facet.(转)
查看>>
WPF MediaElement.Position属性
查看>>
sqoop数据迁移(基于Hadoop和关系数据库服务器之间传送数据)
查看>>
spring mysql多数据源配置
查看>>
[React] Override webpack config for create-react-app without ejection
查看>>
检索 COM 类工厂中 CLSID 为{00024500-0000-0000-C000-000000000046} 的组件时失败,原因是出现以下错误: 80070005。...
查看>>
测试java的父子类化
查看>>
HDOJ 1008
查看>>
安装thrift出现的一些问题
查看>>
makefile编写---单个子目录编译模板
查看>>
Oracle DB_LINK如何使用
查看>>
cv resource
查看>>
关于加快INSERT语句执行速度和HINT /*+ append */及/*+ append nologging */的使用
查看>>
JDK源代码学习系列07----Stack
查看>>
firefox
查看>>
PS批处理的使用
查看>>
七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC 【转】
查看>>
Quartz作业调度框架
查看>>
腾讯云下安装 nodejs + 实现 Nginx 反向代理
查看>>
js-权威指南学习笔记13
查看>>