您的位置:首页 > 其它

bzoj 3190 赛车 半平面交

2017-02-25 12:03 120 查看
   直接写的裸的半平面交,已经有点背不过模板了。。。

   这题卡精度,要用long double ,esp设1e-20。。。

   

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
#include<vector>
#define N 20005
#define double long double
#define inf 1e100
using namespace std;
int n;
const double eps = 1e-20;
struct point//  点&向量
{
double x,y;
point(){};
point(double _x,double _y)
{
x=_x;y=_y;
}
}p
;
// 点减点=向量
point operator - (point a,point b){return point(a.x-b.x,a.y-b.y);}
// 向量+向量=向量 点+向量=点
point operator + (point a,point b){return point(a.x+b.x,a.y+b.y);}
// 向量数乘
point operator * (point a,double b){return point(a.x*b,a.y*b);}
point operator / (point a,double b){return point(a.x/b,a.y/b);}
// 叉积
double cross(point a,point b){return a.x*b.y-a.y*b.x;}
int dcmp(double x)
{
if(max(x,-x)<eps)return 0;
if(x<0)return -1;
return 1;
}
struct line
{
point p,v;
int id;
double ang;
line(){};
line(point pp,point vv,int _id)
{
id=_id;
p=pp;v=vv;
ang=atan2(v.y,v.x);
}
friend bool operator < (line aa,line bb)
{
return aa.ang<bb.ang;
}
}lines
,dep[N*2];int cnt;
point getpoint(line a,line b)
{
point u=a.p-b.p;
double t=cross(b.v,u)/cross(a.v,b.v);
return a.p+a.v*t;
}
bool onright(point a,line b)
{
return cross(b.v,a-b.p)<0;
}
int tot,h,t;
void insert(line l)
{
while(h<t&&onright(p[t-1],l))t--;
while(h<t&&onright(p[h],l))h++;
dep[++t]=l;
if(h<t&&dcmp(dep[t].ang-dep[t-1].ang)==0)
{
t--;
if(onright(dep[t].p,l))dep[t]=l;
}
if(h<t)p[t-1]=getpoint(dep[t],dep[t-1]);
}
void half()
{
h=1;t=0;
for(int i=1;i<=cnt;i++)
{
insert(lines[i]);
}
while(h<t&&onright(p[t-1],dep[h]))t--;
return ;
}
int v
,pos
;
int tt
;
map<pair<int,int>,int>mp;
vector<int>ss
;
int main()
{
//  freopen("in.txt","r",stdin);
lines[++cnt]=line(point(inf,inf),point(-1,0),0);
lines[++cnt]=line(point(0,inf),point(0,-1),0);
lines[++cnt]=line(point(0,0),point(1,0),0);
lines[++cnt]=line(point(inf,0),point(0,1),0);
// 保证答案为空集或一个凸多边形
scanf("%d",&n);int mx=0;int ans=0;
for(int i=1;i<=n;i++)scanf("%d",&pos[i]),mx=max(mx,pos[i]);
for(int i=1;i<=n;i++)scanf("%d",&v[i]);
for(int i=1;i<=n;i++)
{
//      if(i==6501){cout<<pos[i]<<' '<<v[i]<<endl;}
if(pos[i]==mx)tt[++ans]=i;
if(mp.find(make_pair(pos[i],v[i]))!=mp.end())ss[mp[make_pair(pos[i],v[i])]].push_back(i);
else mp[make_pair(pos[i],v[i])]=i,lines[++cnt]=line(point(0,(double)pos[i]),point(1.0,(double)v[i]),i);
}
sort(lines+1,lines+cnt+1);
half();
for(int i=h;i<=t;i++)
{
if(dep[i].id!=0)
{
int ttt=dep[i].id;
if(pos[ttt]!=mx)tt[++ans]=ttt;
for(int j=0;j<ss[ttt].size();j++)
{
if(pos[ss[ttt][j]]!=mx)
{
tt[++ans]=ss[ttt][j];
}
}
}
}
printf("%d\n",ans);
sort(tt+1,tt+ans+1);
for(int i=1;i<ans;i++)printf("%d ",tt[i]);
printf("%d",tt[ans]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: