zoukankan      html  css  js  c++  java
  • POJ1463 Horizontally Visible Segments(区间覆盖)

    题目大意

    给出N条线段的x坐标,以及两个y坐标,要求你求出线段之间两两相互可见的三元组数量

    题解

    先对线段按x坐标升序排序,按顺序进行处理,每次先查询操作,如果当前线段i与其之前的某个线段可见,那么在它们之间建立一条边(用容器来存储),表示它们两相互可见,然后再进行更新操作。处理完之后就是统计了,直接暴力即可。。。还有就是容器记得初始化。。。我被坑了。。。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    using namespace std;
    #define MAXN 8005
    #define lson l,m,s<<1
    #define rson m+1,r,s<<1|1
    typedef struct {
        int x;
        int y1;
        int y2;
    } NODE;
    NODE seg[MAXN];
    int setv[MAXN<<3],hash[MAXN];
    vector<int> g[MAXN];
    bool cmp(NODE a,NODE b)
    {
        return a.x<b.x;
    }
    void PushDown(int s)
    {
        if(setv[s]) {
            setv[s<<1]=setv[s<<1|1]=setv[s];
            setv[s]=0;
        }
    }
    void update(int ql,int qr,int d,int l,int r,int s)
    {
        if(ql<=l&&r<=qr) {
            setv[s]=d;
            return;
        }
        PushDown(s);
        int m=(l+r)>>1;
        if(ql<=m) update(ql,qr,d,lson);
        if(qr>m) update(ql,qr,d,rson);
    }
    void query(int ql,int qr,int d,int l,int r,int s)
    {
        if(setv[s]) {
            if(hash[setv[s]]!=d) {
                g[d].push_back(setv[s]);
                hash[setv[s]]=d;
            }
            return;
        }
        if(l==r) return;
        PushDown(s);
        int m=(l+r)>>1;
        if(ql<=m) query(ql,qr,d,lson);
        if(qr>m) query(ql,qr,d,rson);
    
    }
    int main(void)
    {
        int T,n;
        scanf("%d",&T);
        while(T--) {
            int y1,y2;
            scanf("%d",&n);
            for(int i=1; i<=n; i++) {
                scanf("%d%d%d",&y1,&y2,&seg[i].x);
                seg[i].y1=y1*2;
                seg[i].y2=y2*2;
                g[i].clear();
            }
            memset(setv,0,sizeof(setv));
            memset(hash,0,sizeof(hash));
            sort(seg+1,seg+n+1,cmp);
            for(int i=1; i<=n; i++) {
                query(seg[i].y1,seg[i].y2,i,0,MAXN<<1,1);
                update(seg[i].y1,seg[i].y2,i,0,MAXN<<1,1);
            }
            int ans=0,a,b,t,temp,c;
            for(int i=1; i<=n; i++) {
                t=g[i].size();
                for(int j=0; j<t-1; j++)
                    for(int k=j+1; k<t; k++) {
                        a=g[i][j];
                        b=g[i][k];
                        if(a<b) {
                            temp=a;
                            a=b;
                            b=temp;
                        }
                        c=g[a].size();
                        for(int p=0; p<c; p++)
                            if(g[a][p]==b) {
                                ans++;
                                break;
                            }
                    }
            }
            printf("%d\n",ans);
        }
        return 0;
    }
  • 相关阅读:
    计算机基础--http的基础整理和巩固
    设计方案系列-如何看待前端框架选型 ?
    数据可视化-svg入门基础(二)
    数据可视化系列--svg入门基础(一)
    Jenkins自动部署增加http状态码校验
    快速搭建python程序
    Request 接收参数乱码原理解析三:实例分析
    Request 接收参数乱码原理解析二:浏览器端编码原理
    Request 接收参数乱码原理解析一:服务器端解码原理
    Newtonsoft.Json(Json.Net)学习笔记
  • 原文地址:https://www.cnblogs.com/zjbztianya/p/3092079.html
Copyright © 2011-2022 走看看