zoukankan      html  css  js  c++  java
  • HDU 5517 题解

    题意:给出多重集合A,BA为两个数的有序对多重集合,B为三个数的有序对多重集合,An个元素(ai,bi),Bm个元素(ci,di,ei)(依照多重集合定义,元素可以重复),定义集合C为所有有序对(a,c,d)的集合,其中(a,b)∈A(c,d,e)∈B,且b=e

    TOP(C)为所有有序对(a,b,c)∈C的集合,其中(a,b,c)满足C中不存在一个有序对(d,e,f),使得d>=a && e>=b && f>=c.TOP(C)的元素个数

    1<=N<=100000,1<=m<=100000

    1<=ai,bi<=100000;1<=ci,di<=1000;1=<ei<=100000;

    共1~10组数据,6000MS

    算法/思路:树状数组:直接构造C集合,但其中的a满足a=max{ai,(ai,bi)∈A},然后按a从大到小考虑每个a对应的有序对(b,c),当前有序对满足条件当且仅当对所有曾经扫描过的(bi,ci),有b>bi或c>ci,该过程可用树状数组维护(对于所有有序对(b,c),log(m)时间求出b大于bi时,c的最小值)。时间复杂度O(n+mlogm)

     

    实现细节:由于A,B是多重集合,对于a要加计数器,(b,c)重复考虑即可,树状数组的实现,由于要维护区间[b,maxn],所以把所有位置i变成maxn-i+1丢进去。

     

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    #define rep(i,a,b) for (int i=a;i<=b;++i)
    
    const double eps=1e-7;
    
    struct point{
        double x,y;
        point(){}
        point (double a,double b): x(a),y(b) {}
    
        friend point operator + (const point &a,const point &b){
            return point(a.x+b.x,a.y+b.y);
        }
    
        friend point operator - (const point &a,const point &b){
            return point(a.x-b.x,a.y-b.y);
        }
    
        friend point operator * (const double &r,const point &a){
            return point(r*a.x,r*a.y);
        }
    
        friend bool operator == (const point &a,const point &b){
            return (abs(a.x-b.x)<eps && abs(a.y-b.y)<eps);
        }
    
        double norm(){
            return sqrt(x*x+y*y);
        }
    };
    
    inline double det(point a,point b) {return a.x*b.y-a.y*b.x;}
    
    inline bool line_cross_segment(point s,point t,point a,point b)
    {
        return det(s-a,t-a)*det(s-b,t-b)<-eps;
    }
    
    int n,tot,x,y;
    point s[50],t[50],goal;
    int ans,temp;
    
    int check(point a,point b)
    {
        int temp=0;
        rep(i,1,n)
            if (line_cross_segment(s[i],t[i],a,b)) ++temp;
        return temp;
    }
    
    int main()
    {
        scanf("%d",&n);
        rep(i,1,n) scanf("%lf%lf%lf%lf",&s[i].x,&s[i].y,&t[i].x,&t[i].y);
        ans=100000;
        scanf("%lf%lf",&goal.x,&goal.y);
        rep(i,1,n)
        {
            ans=min(ans,check(s[i],goal));
            ans=min(ans,check(t[i],goal));
        }
        if (n==0) ans=0;
        printf("Number of doors = %d
    ",ans+1);
        return 0;
    }
  • 相关阅读:
    VTK 9.0.1 vtkContextDevice2D 问题
    VTK 中文
    VTK 剪切
    VTK Color Map
    VTK Camera
    VTK Light
    VTK Read Source Object
    VTK Procedural Source Object
    Qt 布局开发问题记录
    Grafana 系列 (7):圖表是否可以数据追踪 (drill down)?(转)
  • 原文地址:https://www.cnblogs.com/terra/p/7027174.html
Copyright © 2011-2022 走看看