zoukankan      html  css  js  c++  java
  • 2732: [HNOI2012]射箭( 半平面交 )

    很久没写题解了= =,来水一发吧= =

    首先这道题很明显就是求y=ax^2+bx的是否有值取,每一个式子都代表着两个半平面,然后直接半平面交就行了

    借鉴了hzwer的代码,还是特别简洁的说

    CODE:

    #include<cstdio>

    #include<iostream>

    #include<algorithm>

    #include<cstring>

    #include<cmath>

    using namespace std;

    typedef pair<long double,long double> ii;

    typedef pair<ii,ii> line;

    #define fi first

    #define se second

    #define maxn 101000

    #define inf 1e15

    #define exp 0

    inline long double cross(ii x,ii y,ii z) {

    return (x.fi-y.fi)*(x.se-z.se)-(x.se-y.se)*(x.fi-z.fi);

    }

    bool cmp(line x,line y) {return cross(x.fi,x.se,y.fi)>exp;}

    line q[maxn*2];

    long double tag[maxn*2];

    bool cmp1(int x,int y) {if (tag[x]==tag[y]) return cmp(q[x],q[y]);return tag[x]<tag[y];} 

    int l;

    inline void init(){

    q[1]=line(ii(-inf,-inf),ii(inf,-inf));

    q[2]=line(ii(inf,-inf),ii(inf,inf));

    q[3]=line(ii(inf,inf),ii(-inf,inf));

    q[4]=line(ii(-inf,inf),ii(-inf,-inf));

    l=4;

    }

    ii inter(line a,line b) {

    long double k1,k2,t;

    k1=cross(a.fi,b.se,a.se);

    k2=cross(a.fi,a.se,b.fi);

    t=k2/(k1+k2);

    return ii(b.fi.fi+t*(b.se.fi-b.fi.fi),b.fi.se+t*(b.se.se-b.fi.se));

    }

    bool jud(line a,line b,line t) {

    ii p=inter(a,b);

    return cross(t.fi,p,t.se)>exp;

    }

    line a[maxn*2],deq[maxn*2];

    int id[maxn*2];

    inline bool check(int n) {

    int num=0;

    for (int i=1;i<=l;i++) if (id[i]<=n*2) a[++num]=q[id[i]];

    int l,r;

    deq[r=l=1]=a[1];

    for (int i=2;i<=n*2;i++) {

    while (r>l&&jud(deq[r-1],deq[r],a[i])) r--;

    while (l<r&&jud(deq[l+1],deq[l],a[i])) l++;

    deq[++r]=a[i];

    }

    while (l<r&&jud(deq[r-1],deq[r],deq[l])) r--;

    while (l<r&&jud(deq[l+1],deq[l],deq[r])) l++;

    return r-l>=2;

    }

    long double cal(long double a,long double b,long double x) {return b/a-a*x;}

    int main(){

    int n;

    scanf("%d",&n);

    init();

    for (int i=1;i<=n;i++) {

    int x1,y1,y2;

    scanf("%d%d%d",&x1,&y1,&y2);

    q[++l]=line(ii(-1,cal(x1,y1,-1)),ii(1,cal(x1,y1,1)));

    q[++l]=line(ii(1,cal(x1,y2,1)),ii(-1,cal(x1,y2,-1)));

    }

    for (int i=1;i<=n*2+4;i++) {tag[i]=atan2(q[i].se.se-q[i].fi.se,q[i].se.fi-q[i].fi.fi);id[i]=i;}

    sort(id+1,id+1+n*2+4,cmp1); 

    int l=2,r=n+2;

    while (l+1<r) {

    int mid=(l+r)>>1;

    if (check(mid)) l=mid;

    else r=mid;

    }

    printf("%d ",check(r)?r-2:l-2);

    return 0;

    }


  • 相关阅读:
    201521123108 《Java程序设计》第八周学习总结
    201521123108 《Java程序设计》第7周学习总结
    201521123108 《Java程序设计》第6周学习总结
    201521123108 《Java程序设计》第5周学习总结
    201521123108 《Java程序设计》第4周学习总结
    201521123108《Java程序设计》第3周学习总结
    201521123107 《Java程序设计》第11周学习总结
    201521123107 《Java程序设计》第10周学习总结
    201521123107 《Java程序设计》第9周学习总结
    201521123107 《Java程序设计》第8周学习总结
  • 原文地址:https://www.cnblogs.com/New-Godess/p/4348895.html
Copyright © 2011-2022 走看看