扫描线概览

poj 1151:

可以说是计算几何的扫描线入门题吧。挺简单的,线段树建树部分要想想。其他就看码力了。

  1 //13435314    ooyyloo    1151    Accepted    748K    0MS    G++    2079B    2014-09-12 16:16:35
  2 #include <cstdio>
  3 #include <algorithm>
  4 #include <iostream>
  5 #include <set>
  6 #define mp make_pair
  7 #define dbg(x) cout<<#x<<"="<<x<<endl
  8 #define foreach(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
  9 using namespace std;
 10 const int maxn=201;
 11
 12 struct line{
 13     double x,y1,y2;
 14     int v;
 15     bool operator< (const line &a) const { return x<a.x; }
 16 }wu[maxn];
 17
 18 int n,nn;
 19 double ans;
 20 set<double> sety;
 21 double hashy[maxn]; int hpo;
 22
 23 //seg tree
 24 double sh[maxn<<2]; int cov[maxn<<2];
 25 void build(int k,int l,int r)
 26 {
 27     sh[k]=cov[k]=0;
 28     if (l+1==r) return;
 29     int mid=l+r>>1;
 30     build(k<<1,l,mid);
 31     build(k<<1|1,mid,r);
 32 }
 33 void update(int k,int l,int r)
 34 {
 35     if (cov[k])      sh[k]=hashy[r]-hashy[l];
 36     else if (l+1==r) sh[k]=cov[k]?hashy[r]-hashy[l]:0;
 37     else              sh[k]=sh[k<<1]+sh[k<<1|1];
 38 }
 39 void modify(int k,int l,int r,int ll,int rr,int v)//we just care about father
 40 {
 41     if (l>=ll&&r<=rr)
 42     {
 43         cov[k]+=v;
 44         update(k,l,r);
 45         return;
 46     }
 47     int mid=l+r>>1;
 48     if (ll<mid) modify(k<<1,l,mid,ll,rr,v);
 49     if (rr>mid) modify(k<<1|1,mid,r,ll,rr,v);
 50     update(k,l,r);
 51 }
 52
 53
 54 void init()
 55 {
 56     nn=n<<1;
 57     sety.clear();
 58
 59     double x1,y1,x2,y2;
 60     for (int i=1;i<=n;i++)
 61     {
 62         scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
 63         wu[i].x=x1; wu[i].y1=y1; wu[i].y2=y2; wu[i].v=1;
 64         wu[i+n].x=x2; wu[i+n].y1=y1; wu[i+n].y2=y2; wu[i+n].v=-1;
 65         sety.insert(y1); sety.insert(y2);
 66     }
 67     hpo=0;
 68     foreach(it,sety) hashy[++hpo]=*it;
 69     //for (auto x:sety) hashy[++hpo]=x;
 70 }
 71 int bs(double d)
 72 {
 73     int l=1,r=hpo,mid;
 74     while (l<=r)
 75     {
 76         mid=l+r>>1;
 77         if (d>hashy[mid]) l=mid+1;
 78         else               r=mid-1;
 79     }
 80     return l;
 81 }
 82 void solve()
 83 {
 84     ans=0.0;
 85     sort(wu+1,wu+1+nn);
 86     modify(1,1,hpo,bs(wu[1].y1),bs(wu[1].y2),wu[1].v);
 87     for (int z=2;z<=nn;z++)
 88     {
 89         ans+=sh[1]*(wu[z].x-wu[z-1].x);
 90         modify(1,1,hpo,bs(wu[z].y1),bs(wu[z].y2),wu[z].v);
 91     }
 92 }
 93 int main()
 94 {
 95     for (int tt=1;scanf("%d",&n)!=EOF;tt++)
 96     {
 97         if (!n) break;
 98         init();
 99         build(1,1,hpo);
100         solve();
101         printf("Test case #%d\n",tt);
102         printf("Total explored area: %.2f\n",ans);
103         puts("");
104     }
105     return 0;
106 }

//scanning line 1

时间: 2024-11-05 20:43:45

扫描线概览的相关文章

【BZOJ】1382: [Baltic2001]Mars Maps (线段树+扫描线)

1382: [Baltic2001]Mars Maps Time Limit: 5 Sec  Memory Limit: 64 MB Description 给出N个矩形,N<=10000.其坐标不超过10^9.求其面积并 Input 先给出一个数字N,代表有N个矩形. 接下来N行,每行四个数,代表矩形的坐标. Output 输出面积并 Sample Input 2 10 10 20 20 15 15 25 30 Sample Output 225 本以为是傻逼题,没想到不容易啊- 线段树+扫描

PHP整体概览

PHP概览及基础入门 1.PHP面向对象 2.smarty 3.AJax 4.PHP访问MYSQL数据库 5.PHP Date()函数 6.PHP正则表达式(PCRE) 7.PHP异常处理 8.PHP错误处理 9.PHP Sessions 10.PHP Cookie 11.文件处理 12.包含文件 13.命名空间(namespace) 14.魔术变量 15.函数 16.循环 17.超级全局变量 18.数组排序 19.数组 20.条件语句 21.运算符 22.字符串变量 23.常量 24.数据类型

PHP概览

PHP概览及基础入门 1.PHP面向对象 2.smarty 3.AJax 4.PHP访问MYSQL数据库 5.PHP Date()函数 6.PHP正则表达式(PCRE) 7.PHP异常处理 8.PHP错误处理 9.PHP Sessions 10.PHP Cookie 11.文件处理 12.包含文件 13.命名空间(namespace) 14.魔术变量 15.函数 16.循环 17.超级全局变量 18.数组排序 19.数组 20.条件语句 21.运算符 22.字符串变量 23.常量 24.数据类型

BZOJ 3022 [Balkan2012]The Best Teams(扫描线+线段树)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3022 [题目大意] 给定n个球员,第i个球员年龄为AGEi,水平为SKILLi. 没有任何两个球员的水平相同.将这些球员按水平排序, 对于一次比赛,你需要选择若干个球员去比赛,但不能同时选择两个水平相邻的球员. m次询问,每次给定a和k,表示要在年龄不超过a的球员中选择不超过k个球员, 请计算skill和的最大值. [题解] 对于询问年龄的限制,我们可以通过扫描线来处理. 我们将所有

【扫描线】Gym - 101190E - Expect to Wait

假设初始人数为0, 将每个时刻在等待的人数写下来,就是求个和. 如果纵坐标看成人数,横坐标看成时间,就是求个面积. 因为初始人数不一定为零,所以离线后扫描线即可回答所有询问. #include<cstdio> #include<algorithm> using namespace std; typedef long long ll; int n,m,e; struct LINE{ int y,l,id; }ls[200010]; bool cmp(const LINE &a

hdu1542 Atlantis(扫描线+线段树+离散)矩形相交面积

题目链接:点击打开链接 题目描写叙述:给定一些矩形,求这些矩形的总面积.假设有重叠.仅仅算一次 解题思路:扫描线+线段树+离散(代码从上往下扫描) 代码: #include<cstdio> #include <algorithm> #define MAXN 110 #define LL ((rt<<1)+1) #define RR ((rt<<1)+2) using namespace std; int n; struct segment{ double l

ASP.NET MVC5(一):ASP.NET MVC概览

ASP.NET MVC概览 ASP.NET MVC是一种构建Web应用程序的框架,它将一般的MVC(Model-View-Controller)模式应用于ASP.NET框架. ASP.NET MVC模式简介 MVC将Web应用程序划分为三个主要的部分,以下是MSDN给出的定义: 模型(Model):模型对象是实现应用程序数据域逻辑的应用程序部件. 通常,模型对象会检索模型状态并将其存储在数据库中. 例如,Product 对象可能会从数据库中检索信息,操作该信息,然后将更新的信息写回到 SQL S

VCSA 6.5 HA配置 之一:架构概览

VCSA 6.5 HA配置之一:架构概览 在VMware vSphere环境中vCenter Server的作用尤其重要,虽然在之前的版本中VMware曾经推出过vCenter Heartbeat来实现vCenter Server的高可用,但是该解决方案早就被VMware抛弃,故此很多管理员都对VMware原生的高可用解决方案翘首以盼,终于在VMware vSphere 6.5 这个版本发布的时候推出了vCenter Server Appliance 6.5的高可用架构,注意的是仅支持vCent

[CF612D] The Union of k-Segments(排序,扫描线)

题目链接:http://codeforces.com/contest/612/problem/D 题意:给n条线段,问覆盖了k次的区间有几个. 扫描线的思想,首先想到的是从左到右扫一遍,遇到出现被覆盖k次的端点,则开始计数,直到覆盖次数小于k为止. 其实可以用线段树做这道题,但是还有更巧妙的办法: 将左端点看作"入",右端点看作"出".每一个线段都是一个区间从入到出,入指的是覆盖次数+1,出指的是覆盖次数-1. 按照左端点升序排列,每遇到一个"入"