bzoj1007: [HNOI2008]水平可见直线 凸包
2014-11-28 23:36
218 查看
一种类似于凸包的做法。
相同斜率的直线 b小的会被b大的遮住。
不同斜率的直线最后就会构成一个像开口向上的二次函数的图像。
按照斜率排序,再一个个加到栈里面。
相同斜率的直接判断,不同斜率的直线间可以发现,设栈顶编号为(top);如果当前直线和栈中编号为(top-2)的交点横坐标在 直线(top-1)和(top-2)交点的左侧,那么当前直线就把top遮住了。
建议自己画图。
交点横坐标直接联立两个方程就可以了。
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <stack>
using namespace std;
#define esp 1e-8
#define maxn 51000
struct node
{
double a,b;
int id;
}save[maxn];
int n;
bool cmp(node aa,node bb)
{
if(fabs(aa.a-bb.a)<esp) return aa.b<bb.b;
return aa.a<bb.a;
}
node que[maxn];
int top=0;
double getp(node aa,node bb)
{
double tmp;
tmp=(bb.b-aa.b)/(aa.a-bb.a);
return tmp;
}
void deal(node aa)
{
while(top)
{
if(fabs(que[top].a-aa.a)<esp)
{
top--;
}
else if(top>1&&(getp(aa,que[top-1])<=getp(que[top],que[top-1]))) top--;
else break;
}
top++;
que[top]=aa;
}
bool ans[maxn];
void solve()
{
for(int i=1;i<=n;i++)
{
deal(save[i]);
}
for(int i=1;i<=top;i++)
{
ans[que[i].id]=1;
}
for(int i=1;i<=n;i++)
{
if(ans[i])
printf("%d ",i);
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%lf%lf",&save[i].a,&save[i].b);
save[i].id=i;
}
sort(save+1,save+1+n,cmp);
solve();
return 0;
}
相同斜率的直线 b小的会被b大的遮住。
不同斜率的直线最后就会构成一个像开口向上的二次函数的图像。
按照斜率排序,再一个个加到栈里面。
相同斜率的直接判断,不同斜率的直线间可以发现,设栈顶编号为(top);如果当前直线和栈中编号为(top-2)的交点横坐标在 直线(top-1)和(top-2)交点的左侧,那么当前直线就把top遮住了。
建议自己画图。
交点横坐标直接联立两个方程就可以了。
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <stack>
using namespace std;
#define esp 1e-8
#define maxn 51000
struct node
{
double a,b;
int id;
}save[maxn];
int n;
bool cmp(node aa,node bb)
{
if(fabs(aa.a-bb.a)<esp) return aa.b<bb.b;
return aa.a<bb.a;
}
node que[maxn];
int top=0;
double getp(node aa,node bb)
{
double tmp;
tmp=(bb.b-aa.b)/(aa.a-bb.a);
return tmp;
}
void deal(node aa)
{
while(top)
{
if(fabs(que[top].a-aa.a)<esp)
{
top--;
}
else if(top>1&&(getp(aa,que[top-1])<=getp(que[top],que[top-1]))) top--;
else break;
}
top++;
que[top]=aa;
}
bool ans[maxn];
void solve()
{
for(int i=1;i<=n;i++)
{
deal(save[i]);
}
for(int i=1;i<=top;i++)
{
ans[que[i].id]=1;
}
for(int i=1;i<=n;i++)
{
if(ans[i])
printf("%d ",i);
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%lf%lf",&save[i].a,&save[i].b);
save[i].id=i;
}
sort(save+1,save+1+n,cmp);
solve();
return 0;
}
相关文章推荐
- [半平面交对偶凸包] BZOJ 1007 [HNOI2008]水平可见直线
- BZOJ 1007 [HNOI2008]水平可见直线 ——半平面交 凸包
- BZOJ1007 [HNOI2008]水平可见直线 计算几何 单调栈维护上凸包
- BZOJ 1007: [HNOI2008]水平可见直线 几何
- [单调栈] bzoj1007: [HNOI2008]水平可见直线
- 【几何】[HNOI2008][BZOJ1007]水平可见直线
- bzoj 1007: [HNOI2008]水平可见直线
- 【BZOJ 1007】【HNOI 2008】水平可见直线 【计算几何】
- bzoj1007: [HNOI2008]水平可见直线
- BZOJ 1007 HNOI 2008 水平可见直线 计算几何+栈
- 【BZOJ 1007】[HNOI2008]水平可见直线 半平面交
- BZOJ 1007 [HNOI2008]水平可见直线===数学相关
- [BZOJ 1007][HNOI2008]水平可见直线
- [BZOJ 1007][HNOI2008]水平可见直线:单调栈
- bzoj 1007 : [HNOI2008]水平可见直线 计算几何
- BZOJ 1007 [HNOI2008]水平可见直线
- [BZOJ1007](HNOI2008)水平可见直线(半平面交习题)
- 【单调栈】BZOJ1007 [HNOI2008]水平可见直线
- [BZOJ1007]HNOI2008水平可见直线|计算几何|栈
- 【BZOJ 1007】【HNOI 2008】水平可见直线 解析几何