# 小学半平面交

#include <cstdio>
#include <cstring>
#include <algorithm>
const int N=10010;
struct Race{
double k,b;
int id;
}race[N],stack[N];
int top;
inline bool comp(Race a,Race b){
return a.k<b.k||(a.k==b.k&&a.b>b.b);
}
int n;
bool good[N];
inline void Init(){
scanf("%d",&n);
int i;
for(i=1;i<=n;++i)
scanf("%lf",&race[i].b);
for(i=1;i<=n;++i)
scanf("%lf",&race[i].k),race[i].id=i;
}
inline bool check(Race a,Race b,Race c){
double x=(double)(b.b-a.b)/(a.k-b.k);
double y=a.k*x+a.b;
return y>=c.k*x+c.b;
}
inline void Work(){
int i,j;
std::sort(race+1,race+(n+1),comp);
j=0;
race[++j]=race[1];
for(i=2;i<=n;++i)
if(race[i].k!=race[j].k||(race[i].k==race[j].k&&race[i].b==race[j].b))
race[++j]=race[i];
stack[++top]=(Race){1./0.,0.,0};
for(i=1;i<=j;++i){
while(top>1&&!check(stack[top],stack[top-1],race[i]))--top;
stack[++top]=race[i];
}
}
inline void Print(){
int i;
for(i=1;i<=top;++i)
good[stack[i].id]=true;
printf("%d\n",top-1);
for(i=1;i<=n;++i)
if(good[i])
printf("%d ",i);
puts("");
}
int main(){
Init(),Work(),Print();
return 0;
}
bzoj3190:[JLOI2013]赛车
#include <cstdio>
#include <cstring>
#include <algorithm>
const int N=110;
const double oo=1e10;
const double eps=1e-6;
int n;
double s;
struct Peo{
double k,b;
inline void redef(double x,double y){
k=1./x-1./y;
b=s/y;
}
inline double query(double pos){
return k*pos+b;
}
}peo[N];
inline double query(double pos){
double ret=oo;
for(int i=1;i<n;++i)
ret=std::min(ret,peo[i].query(pos));
ret-=peo[n].query(pos);
return ret;
}
int main(){
scanf("%lf%d",&s,&n);
int i;
double l,r,mid1,mid2,x,y,ans1=0.,ans2=-oo;
for(i=1;i<=n;++i){
scanf("%lf%lf",&x,&y);
x/=3600,y/=3600;
peo[i].redef(x,y);
}
l=0.,r=s;
while(l+eps<r){
mid1=(r-l)/3+l;
mid2=r-(r-l)/3;
x=query(mid1);
y=query(mid2);
if(x<=y)
ans2=y,ans1=mid2,l=mid1;
else
ans2=x,ans1=mid1,r=mid2;
}
x=query(0);
if(x>=ans2)ans2=x,ans1=0;
if(ans2<0)puts("NO");
else printf("%.2f %.2f %.0f\n",ans1,s-ans1,ans2);
return 0;
}
bzoj2765:[JLOI2010]铁人双项比赛
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
const int N=310;
const double oo=1e10;
const double eps=1e-8;
struct Poi{
double x,y;
inline friend double operator *(Poi a,Poi b){
return a.x*b.y-a.y*b.x;
}
inline friend Poi operator -(Poi a,Poi b){
return (Poi){a.x-b.x,a.y-b.y};
}
}dia[N];
struct Line{
Poi s,t;
double k;
inline void redef(Poi a,Poi b){
s=a,t=b,k=std::atan2(b.y-a.y,b.x-a.x);
}
}line[N],stack[N];
int top;
inline bool comp(Line a,Line b){
return a.k==b.k?(b.s-a.s)*(b.t-a.s)>0:a.k<b.k;
}
int n;
inline Poi point(Line a,Line b){
Poi ret;
double s1=(b.s-a.s)*(b.t-a.s);
double s2=(b.t-a.t)*(b.s-a.t);
ret.x=(s1*a.t.x+s2*a.s.x)/(s1+s2);
ret.y=(s1*a.t.y+s2*a.s.y)/(s1+s2);
return ret;
}
inline bool check(Line a,Line b,Line c){
Poi poi=point(a,b);
return (c.s-poi)*(c.t-poi)>0;
}
inline void Init(){
scanf("%d",&n);
int i;
for(i=1;i<=n;++i)
scanf("%lf",&dia[i].x);
for(i=1;i<=n;++i)
scanf("%lf",&dia[i].y);
dia[0]=(Poi){dia[1].x,oo};
dia[n+1]=(Poi){dia[n].x,oo};
++n;
for(i=1;i<=n;++i)
line[i].redef(dia[i-1],dia[i]);
}
inline void Work(){
std::sort(line+1,line+(n+1),comp);
int i,j;
j=0;
line[++j]=line[1];
for(i=2;i<=n;++i)
if(line[i].k!=line[j].k)
line[++j]=line[i];
stack[++top]=line[1];
stack[++top]=line[2];
for(i=3;i<=j;++i){
while(top>1&&!check(stack[top],stack[top-1],line[i]))--top;
stack[++top]=line[i];
}
}
inline double query(double pos){
Poi p1=(Poi){pos,0},p2=(Poi){pos,oo},poi;
Line tmp;
tmp.redef(p1,p2);
double ret=-oo;
for(int i=2;i<top;++i){
poi=point(tmp,stack[i]);
ret=std::max(ret,poi.y);
}
return ret;
}
inline void Print(){
int i,at;
double ans=oo;
Poi poi;
for(i=1;i<n;++i)
ans=std::min(ans,query(dia[i].x)-dia[i].y);
at=1;
for(i=3;i<top;++i){
poi=point(stack[i-1],stack[i]);
while(poi.x>=dia[at+1].x)++at;
ans=std::min(ans,poi.y-((dia[at+1].y-dia[at].y)*(poi.x-dia[at].x)/(dia[at+1].x-dia[at].x)+dia[at].y));
}
printf("%.3f\n",ans);
}
int main(){
//freopen("rio.txt","r",stdin);
//freopen("wq.txt","w",stdout);
Init(),Work(),Print();
return 0;
}
bzoj1038:[ZJOI2008]瞭望塔
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
const int N=110;
double s=1;
int n,v[N],u[N],w[N];
struct Line{
double a,b,c,k;
inline void redef(double x,double y,double z){
a=x,b=y,c=z;
if(x<0)x=-x;
if(x)a/=x,b/=x,c/=x;
k=std::atan2(-a,b);
}
}line[N],queue[N];
inline bool comp(Line a,Line b){
return a.k!=b.k?a.k<b.k:a.c<b.c;
}
inline bool check(Line a,Line b,Line c){
double x=(b.c*a.b-a.c*b.b)/(a.a*b.b-a.b*b.a);
double y=(b.c*a.a-a.c*b.a)/(a.b*b.a-a.a*b.b);
return c.a*x+c.b*y+c.c>0;
}
inline void Init(){
scanf("%d",&n);
int i;
for(i=1;i<=n;++i)
scanf("%d%d%d",&v[i],&u[i],&w[i]);
}
inline bool check(int id){
int m=5,i,j;
line[1].redef(1,0,0);
line[2].redef(-1,0,s);
line[3].redef(0,1,0);
line[4].redef(0,-1,s);
line[5].redef(-1,-1,s);
double a,b,c;
for(i=1;i<=n;++i){
if(i==id)continue;
if(v[id]<=v[i]&&u[id]<=u[i]&&w[id]<=w[i])return false;
a=1./v[id]-1./v[i];
b=1./u[id]-1./u[i];
c=1./w[id]-1./w[i];
++m;
line[m].redef(c-a,c-b,-c*s);
}
std::sort(line+1,line+(m+1),comp);
j=0;
line[++j]=line[1];
for(i=2;i<=m;++i)
if(line[i].k!=line[j].k)
line[++j]=line[i];
queue[tail++]=line[1];
queue[tail++]=line[2];
for(i=3;i<=j;++i){
queue[tail++]=line[i];
}
}
inline void Print(){
int i;
for(i=1;i<=n;++i)
puts(check(i)?"Yes":"No");
}
int main(){
Init();Print();
return 0;
}
bzoj3800:Saber VS Lancer
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
const int N=100010;
const double oo=1e20;
int n,cnt;
struct Line{
double a,b,c,k;
int id;
inline void redef(double x,double y,double z,int name){
//如果x、y都为0,那么若z>=0成立,则整张图都成立,若不成立,则整张图都不成立
id=name;
a=x,b=y,c=z;
if(x<0)x=-x;
if(x)a/=x,b/=x,c/=x;
else{
if(y<0)y=-y;
if(y)a/=y,b/=y,c/=y;
}
k=std::atan2(-a,b);
//讨论一下4种平行、外加Delta的计算,就会发现这是对的
}
}keep[N<<1],line[N<<1],queue[N<<1];
inline bool comp(Line a,Line b){
return a.k!=b.k?a.k<b.k:a.c<b.c;
//在我们上面进行了除x且除y的操作之后,这样是对的
}
inline bool check(Line a,Line b,Line c){
double x=(a.b*b.c-b.b*a.c)/(b.b*a.a-a.b*b.a);
double y=(a.a*b.c-b.a*a.c)/(b.a*a.b-a.a*b.b);
return c.a*x+c.b*y+c.c>=0;
//手推一下就能出来,只要记住x的主料为b、y的主料为a、上下主料相反、单项相反、上c下反即可
}
inline bool check(int k){
int i,j=0;
for(i=1;i<=cnt;++i)
if(keep[i].id<=k&&(j==0||keep[i].k!=line[j].k))
line[++j]=keep[i];
queue[tail++]=line[1];
queue[tail++]=line[2];
for(i=3;i<=j;++i){
queue[tail++]=line[i];
}
}
inline void Init(){
cnt=4;
keep[1].redef(1,0,oo,0);
keep[2].redef(-1,0,0,0);
keep[3].redef(0,1,oo,0);
keep[4].redef(0,-1,oo,0);
scanf("%d",&n);
int i,j,x,y,z;
for(i=1;i<=n;++i){
scanf("%d%d%d",&x,&y,&z);
keep[++cnt].redef((double)x*x,x,-y,i);
keep[++cnt].redef(-(double)x*x,-x,z,i);
}
std::sort(keep+1,keep+(cnt+1),comp);
}
inline void Work(){
int l=1,r=n,mid,ans=0;
while(l<=r){
mid=(l+r)>>1;
if(check(mid))
ans=mid,l=mid+1;
else
r=mid-1;
}
printf("%d\n",ans);
}
int main(){
Init(),Work();
return 0;
}
bzoj2732:[HNOI2012]射箭
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define pf(a) ((double)(a)*(a))
const int N=610;
int n;
struct V{
int to,next;
}c[N*N*2];
int first[N],t;
int di[N],qu[N],front,back;
int aks[N],wai[N];
c[++t].to=y,c[t].next=first[x],first[x]=t;
}
struct Line{
double a,b,c,k;
int id;
inline void redef(double x,double y,double z,int name){
a=x,b=y,c=z,id=name;
if(x<0)x=-x;
if(x)a/=x,b/=x,c/=x;
else{
if(y<0)y=-y;
if(y)a/=y,b/=y,c/=y;
}
k=std::atan2(-a,b);
}
}line[N],queue[N];
inline bool comp(Line a,Line b){
return a.k!=b.k?a.k<b.k:a.c<b.c;
}
inline bool check(Line a,Line b,Line c){
double x=(a.b*b.c-b.b*a.c)/(b.b*a.a-a.b*b.a);
double y=(a.a*b.c-b.a*a.c)/(b.a*a.b-a.a*b.b);
return c.a*x+c.b*y+c.c>0;
}
inline void build(int id,int li,int im){
int i,j=1,m=4;
line[1].redef(1,0,0,0);
line[2].redef(-1,0,li,0);
line[3].redef(0,1,0,0);
line[4].redef(0,-1,im,0);
double a,b,c;
for(i=1;i<=n;++i){
if(i==id)continue;
a=2*aks[id]-2*aks[i];
b=2*wai[id]-2*wai[i];
c=pf(aks[i])-pf(aks[id])+pf(wai[i])-pf(wai[id]);
line[++m].redef(a,b,c,i);
}
std::sort(line+1,line+(m+1),comp);
for(i=2;i<=m;++i)
if(line[i].k!=line[j].k)
line[++j]=line[i];
queue[tail++]=line[1];
queue[tail++]=line[2];
for(i=3;i<=j;++i){
queue[tail++]=line[i];
}
}
inline int bfs(int s){
memset(di,-1,sizeof(di));
front=back=0;
qu[back++]=s;
di[s]=0;
int x,i;
while(front!=back){
x=qu[front++];
for(i=first[x];i;i=c[i].next)
if(di[c[i].to]==-1){
if(!c[i].to)return di[x]+1;
di[c[i].to]=di[x]+1;
qu[back++]=c[i].to;
}
}
}
inline void Main(){
memset(first,0,sizeof(first)),t=0;
scanf("%d",&n);
int i,w,q,l,m,id;
double min,dis;
scanf("%d%d%d%d",&l,&m,&w,&q);
if(n==0){
puts("0");
return;
}
for(i=1;i<=n;++i){
scanf("%d%d",&aks[i],&wai[i]);
dis=pf(w-aks[i])+pf(q-wai[i]);
if(i==1||dis<min)
id=i,min=dis;
}
for(i=1;i<=n;++i)
build(i,l,m);
printf("%d\n",bfs(id));
}
int main(){
int T;
scanf("%d",&T);
while(T--)
Main();
return 0;
}
bzoj3199:[Sdoi2013]escape

posted @ 2018-04-10 19:29  TS_Hugh  阅读(...)  评论(... 编辑 收藏