zoukankan      html  css  js  c++  java
  • hdu 5862 Counting Intersections

    传送门:hdu 5862 Counting Intersections

    题意:对于平行于坐标轴的n条线段,求两两相交的线段对有多少个,包括十,T型

    官方题解:由于数据限制,只有竖向与横向的线段才会产生交点,所以先对横向线段按x端点排序,每次加入一个线段,将其对应的y坐标位置+1,当出现一个竖向线段时,查询它的两个y端点之间的和即为交点个数.

    注意点:对x坐标排序是对所有线段端点排序;因为可能出现 “  1-1  “ 这样的情况,所以对于横着的线段,需要进行首尾x坐标处理;我的方法是对于x坐标,先按大小排序,如果大小相同,按先横后竖的方式排序,那么对于 “ 1- ”这样的情况,是能够正确计算的,对于“ -1” 这样的情况,就得对横着的线段的右端点+1处理

    总结:这类题型非常常见,处理方法也很巧妙,有必要熟练运用。2016百度之星复赛的1003 拍照 也是同类型的题

    /**************************************************************
        Problem:hdu 5862 Counting Intersections
        User: youmi
        Language: C++
        Result: Accepted
        Time:2199MS
        Memory:9124K
    ****************************************************************/
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    //#include<bits/stdc++.h>
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <map>
    #include <stack>
    #include <set>
    #include <sstream>
    #include <cmath>
    #include <queue>
    #include <deque>
    #include <string>
    #include <vector>
    #define zeros(a) memset(a,0,sizeof(a))
    #define ones(a) memset(a,-1,sizeof(a))
    #define sc(a) scanf("%d",&a)
    #define sc2(a,b) scanf("%d%d",&a,&b)
    #define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c)
    #define scs(a) scanf("%s",a)
    #define sclld(a) scanf("%I64d",&a)
    #define pt(a) printf("%d
    ",a)
    #define ptlld(a) printf("%I64d
    ",a)
    #define rep(i,from,to) for(int i=from;i<=to;i++)
    #define irep(i,to,from) for(int i=to;i>=from;i--)
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define Min(a,b) ((a)<(b)?(a):(b))
    #define lson (step<<1)
    #define rson (lson+1)
    #define esp 1e-6
    #define oo 0x3fffffff
    #define TEST cout<<"*************************"<<endl
    const double pi=4*atan(1.0);
    
    using namespace std;
    typedef long long ll;
    template <class T> inline void read(T &n)
    {
        char c; int flag = 1;
        for (c = getchar(); !(c >= '0' && c <= '9' || c == '-'); c = getchar()); if (c == '-') flag = -1, n = 0; else n = c - '0';
        for (c = getchar(); c >= '0' && c <= '9'; c = getchar()) n = n * 10 + c - '0'; n *= flag;
    }
    ll Pow(ll base, ll n, ll mo)
    {
        if (n == 0) return 1;
        if (n == 1) return base % mo;
        ll tmp = Pow(base, n >> 1, mo);
        tmp = (ll)tmp * tmp % mo;
        if (n & 1) tmp = (ll)tmp * base % mo;
        return tmp;
    }
    //***************************
    
    int n;
    const int maxn=100000+10;
    const ll mod=1000000007;
    
    typedef struct Point
    {
        int x,y;
        int id;
        Point(){};
        Point(int _x,int _y,int _id)
        {
            x=_x,y=_y,id=_id;
        }
    }point;
    typedef struct Line
    {
        point s,e;
        int dir;
        Line(){};
        Line(point  _s,point  _e,int _dir)
        {
            s=_s,e=_e,dir=_dir;
        }
    }line;
    line ln[maxn];
    point p[maxn<<1];
    int y[maxn<<1];
    bool vis[maxn];
    bool cmp(point a,point b)
    {
        return a.x==b.x?ln[a.id].dir<ln[b.id].dir:a.x<b.x;
    }
    ll c[maxn<<1];
    int lowbit(int x)
    {
        return x&(-x);
    }
    void update(int x,int val)
    {
        while(x<=2*n)
        {
            c[x]+=val;
            x+=lowbit(x);
        }
    }
    ll query(int x)
    {
        ll res=0;
        while(x)
        {
            res+=c[x];
            x-=lowbit(x);
        }
        return res;
    }
    
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        #endif
        int T_T;
        scanf("%d",&T_T);
        for(int kase=1;kase<=T_T;kase++)
        {
            sc(n);
            int x1,y1,x2,y2;
            rep(i,1,n)
            {
                scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
                if(y1>y2||x1>x2)
                {
                    swap(y1,y2);
                    swap(x1,x2);
                }
                p[i*2-1]=Point(x1,y1,i);
                p[i*2]=Point(x2,y2,i);
                y[i*2-1]=y1,y[i*2]=y2;
                if(y1==y2)
                    ln[i]=Line(Point(x1,y1,i),Point(x2,y2,i),0),p[i*2].x++;//横线的右端点+1
                else if(x1==x2)
                    ln[i]=Line(Point(x1,y1,i),Point(x2,y2,i),1);
            }
            sort(p+1,p+1+2*n,cmp);
            sort(y+1,y+1+2*n);
            int k=unique(y+1,y+1+2*n)-(y+1);
            rep(i,1,2*n)
                p[i].y=lower_bound(y+1,y+1+k,p[i].y)-(y);
            rep(i,1,n)
                ln[i].s.y=lower_bound(y+1,y+1+k,ln[i].s.y)-(y),ln[i].e.y=lower_bound(y+1,y+1+k,ln[i].e.y)-(y);
            ll ans=0;
            zeros(c);
            zeros(vis);
            rep(i,1,2*n)
            {
                int dir=ln[p[i].id].dir;
                if(dir==0)
                {
                    if(vis[p[i].id])
                        update(p[i].y,-1);
                    else
                    {
                        vis[p[i].id]=1;
                        update(p[i].y,1);
                    }
                }
                else
                {
                    if(vis[p[i].id])
                        continue;
                    vis[p[i].id]=1;
                    ll temp=query(ln[p[i].id].e.y);
                    temp-=query(ln[p[i].id].s.y-1);
                    ans+=temp;
                }
            }
            ptlld(ans);
        }
    }
    不为失败找借口,只为成功找方法
  • 相关阅读:
    学习视频收集
    vscode 编译器插件
    vue2.0父子组件之间传值
    js 案例
    插件
    【转】30分钟掌握 C#6
    【初码干货】关于.NET玩爬虫这些事
    上机作业七 系统进程与计划任务管理
    客户端与服务器双向密钥对验证
    DHCP中继配置
  • 原文地址:https://www.cnblogs.com/youmi/p/5788901.html
Copyright © 2011-2022 走看看