zoukankan      html  css  js  c++  java
  • ZOJ 3157 Weapon --计算几何+树状数组

    题意:给一些直线,问这些直线在直线x=L,x=R之间有多少个交点。

    讲解见此文:http://blog.sina.com.cn/s/blog_778e7c6e0100q64a.html

    首先将直线分别跟x=L+eps,x=R-eps(防止出现相同纵坐标,故+-eps)求他们的交点,求的纵坐标为low,high,首先按low从大到小排序,一次赋予一个ind值,再按high从大到小排序,此时ind的逆序对数即为(L,R)内的交点个数。成功将计算几何问题向树状数组转化。求逆序对数可用归并排序或者树状数组解决。

    代码:(树状数组)

    #include <iostream>
    #include <cmath>
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #define eps 1e-5
    using namespace std;
    #define N 10007
    
    struct node
    {
        double x,y;
    };
    
    struct Line
    {
        node a,b;
        int ind;
        double low,high;
    }line[N];
    
    int c[N],n;
    
    int cmp(Line ka,Line kb)
    {
        return ka.low > kb.low;
    }
    
    int cmp2(Line ka,Line kb)
    {
        return ka.high > kb.high;
    }
    
    int lowbit(int x){ return x & (-x); }
    
    void modify(int x)
    {
        while(x <= n)
            c[x]++,x += lowbit(x);
    }
    
    int getsum(int x)
    {
        int res = 0;
        while(x > 0)
            res += c[x],x -= lowbit(x);
        return res;
    }
    
    int main()
    {
        int i,x,j;
        double L,R;
        while(scanf("%d",&n)!=EOF)
        {
            memset(c,0,sizeof(c));
            for(i=1;i<=n;i++)
                scanf("%lf%lf%lf%lf",&line[i].a.x,&line[i].a.y,&line[i].b.x,&line[i].b.y);
            scanf("%lf%lf",&L,&R);
            L += eps,R -= eps;
            for(i=1;i<=n;i++)
            {
                double k = (line[i].b.y-line[i].a.y)/(line[i].b.x-line[i].a.x);
                line[i].low = k*(L-line[i].a.x) + line[i].a.y;
                line[i].high = k*(R-line[i].a.x) + line[i].a.y;
            }
            sort(line+1,line+n+1,cmp);
            for(i=1;i<=n;i++)
                line[i].ind = i;
            sort(line+1,line+n+1,cmp2);
            int ans = 0;
            for(i=1;i<=n;i++)
            {
                modify(line[i].ind);
                ans += i - getsum(line[i].ind);
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    JDBC_查询
    微信web小程序开发1
    小型人口普查系统2
    小型人口普查系统1
    JSP内置对象作用域
    Session和Cookie的区别
    Cookie
    Session
    c++中嵌入python
    目标文件obj的各段 2
  • 原文地址:https://www.cnblogs.com/whatbeg/p/3944694.html
Copyright © 2011-2022 走看看