HDU 1255 覆盖的面积 (扫描线 线段树 离散化 矩形面积并)
题意:中文题意。
分析:纯手敲,与上一道题目很相似,但是刚开始我以为只是把cnt》=0改成cnt>=2就行了,、
但是后来发现当当前加入的线段的范围之前 还有线段的时候就不行了,因为虽然现在都不等于
2,但是之前的那个线段加上现在的已经覆盖2次了。
- #include <iostream>
- #include <cstdio>
- #include <vector>
- #include <cstring>
- #include <cstdlib>
- #include <algorithm>
- #define LL __int64
- #define lson l, mid, 2*rt
- #define rson mid+1, r, 2*rt+1
- const int maxn = +;
- using namespace std;
- int n;
- double y[maxn];
- struct node
- {
- int l, r, c;
- double cnt, lf, rf, more; //cnt还是代表覆盖的长度,增加了more代表两次及以上覆盖的长度
- }tr[*maxn];
- struct Line
- {
- double x, y1, y2;
- int f;
- }line[maxn];
- bool cmp(Line a, Line b)
- {
- return a.x < b.x;
- }
- void build(int l, int r, int rt)
- {
- tr[rt].l = l; tr[rt].r = r;
- tr[rt].c = ; tr[rt].cnt = ;
- tr[rt].more = ;
- tr[rt].rf = y[r]; tr[rt].lf = y[l];
- if(l+==r) return;
- int mid = (l+r)/;
- build(l, mid, *rt);
- build(mid, r, *rt+);
- }
- void calen(int rt)
- {
- if(tr[rt].c==)
- {
- if(tr[rt].l+==tr[rt].r)
- {
- tr[rt].cnt = ; tr[rt].more = ;
- }
- else
- {
- tr[rt].cnt = tr[*rt].cnt+tr[*rt+].cnt;
- tr[rt].more = tr[*rt].more+tr[*rt+].more;
- }
- }
- if(tr[rt].c==) //注意这一步是关键
- {
- tr[rt].cnt = tr[rt].rf-tr[rt].lf;
- if(tr[rt].l+==tr[rt].r) //因为没有注意是否到最后,错了一遍
- tr[rt].more = ;
- else
- tr[rt].more = tr[*rt].cnt + tr[*rt+].cnt; //为1的时候如果下面也有就加上
- }
- if(tr[rt].c>=)
- {
- tr[rt].more = tr[rt].rf-tr[rt].lf;
- tr[rt].cnt = tr[rt].more;
- }
- }
- void update(int rt, Line e)
- {
- if(e.y1==tr[rt].lf && e.y2==tr[rt].rf)
- {
- tr[rt].c += e.f;
- calen(rt);
- return;
- }
- if(e.y2<=tr[*rt].rf) update(*rt, e);
- else if(e.y1>=tr[*rt+].lf) update(*rt+, e);
- else
- {
- Line tmp;
- tmp = e;
- tmp.y2 = tr[*rt].rf; update(*rt, tmp);
- tmp = e;
- tmp.y1 = tr[*rt+].lf; update(*rt+, tmp);
- }
- calen(rt);
- }
- int main()
- {
- int t, i, cnt;
- double x1, x2, y1, y2, ans;
- scanf("%d", &t);
- while(t--)
- {
- scanf("%d", &n);
- cnt = ; ans = ;
- for(i = ; i <= n; i++)
- {
- scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
- line[cnt].x = x1; line[cnt].y1 = y1;
- line[cnt].y2 = y2; line[cnt].f = ;
- y[cnt++] = y1;
- line[cnt].x = x2; line[cnt].y1 = y1;
- line[cnt].y2 = y2; line[cnt].f = -;
- y[cnt++] = y2;
- }
- sort(y+, y+cnt);
- sort(line+, line+cnt, cmp);
- cnt --;
- build(, cnt, );
- update(, line[]);
- for(i = ; i <= cnt; i++)
- {
- ans += tr[].more*(line[i].x - line[i-].x);
- update(, line[i]);
- }
- printf("%.2lf\n", ans);
- }
- return ;
- }
HDU 1255 覆盖的面积 (扫描线 线段树 离散化 矩形面积并)的更多相关文章
- HDU - 1255 覆盖的面积(线段树求矩形面积交 扫描线+离散化)
链接:线段树求矩形面积并 扫描线+离散化 1.给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. 2.看完线段树求矩形面积并 的方法后,再看这题,求的是矩形面积交,类同. 求面积时,用被覆 ...
- POJ 1151Atlantis 扫描线+线段树求矩形面积并
题目链接 #include <iostream> #include <vector> #include <cstdio> #include <cstring& ...
- hdu 5091 给定矩形覆盖尽量多点 扫描线+线段树
http://acm.hdu.edu.cn/showproblem.php?pid=5091 给你10000以内的敌舰的坐标(即分别为x,y),要求用W*H的矩形去围住一个区域,使得这个区域内的敌舰最 ...
- POJ 1151 / HDU 1542 Atlantis 线段树求矩形面积并
题意:给出矩形两对角点坐标,求矩形面积并. 解法:线段树+离散化. 每加入一个矩形,将两个y值加入yy数组以待离散化,将左边界cover值置为1,右边界置为2,离散后建立的线段树其实是以y值建的树,线 ...
- 【hdu1542】线段树求矩形面积并
分割线内容转载自http://hzwer.com/879.html ------------------------------------------------------------------ ...
- POJ 1151 Atlantis 线段树求矩形面积并 方法详解
第一次做线段树扫描法的题,网搜各种讲解,发现大多数都讲得太过简洁,不是太容易理解.所以自己打算写一个详细的.看完必会o(∩_∩)o 顾名思义,扫描法就是用一根想象中的线扫过所有矩形,在写代码的过程中, ...
- HDU 1542:Atlantis(扫描线+线段树 矩形面积并)***
题目链接 题意 给出n个矩形,求面积并. 思路 使用扫描线,我这里离散化y轴,按照x坐标从左往右扫过去.离散化后的y轴可以用线段树维护整个y上面的线段总长度,当碰到扫描线的时候,就可以统计面积.这里要 ...
- POJ1151Atlantis 矩形面积并[线段树 离散化 扫描线]
Atlantis Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 21734 Accepted: 8179 Descrip ...
- POJ 1151Atlantis 矩形面积并[线段树 离散化 扫描线]
Atlantis Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 21734 Accepted: 8179 Descrip ...
随机推荐
- Liferay SDK 6.2与7.0中build.[$username].properties 文件的配置
这篇文章是针对刚开始开发Liferay的新手写的,希望能够帮到刚入门的开发者减少一些配置上的麻烦. 前提: 1. 下载了Liferay IDE(Liferay的官方开发工具) 2.下载了Liferay ...
- PDF.NET框架操作——工具应用(一)
PDF.NET是个开源的项目其解决UI层(WinForm / Web)控件数据绑定.映射与查询: BLL层实体对象查询(OQL):DAL层SQL语句和.NET数据访问代码映射(查看 SQL-MAP ...
- PythonChallenge 1:恺撒密码的解码
题目: 解题思路:根据图中的K→M,O→Q,E→G,我们可以发现K,O,E这三个字母都向后移动了2位.据说恺撒率先使用了这一加密方法,因此将其命名为恺撒密码.它的基本思想是:通过把字母移动一定的位数来 ...
- C# textbox 滚动条 随文本输入 滚动
tb_Log.SelectionStart = tb_Log.Text.Length;//设置光标位置 tb_Log.ScrollToCaret();//随文本输入 滚动
- HDU 1385 Minimum Transport Cost (最短路,并输出路径)
题意:给你n个城市,一些城市之间会有一些道路,有边权.并且每个城市都会有一些费用. 然后你一些起点和终点,问你从起点到终点最少需要多少路途. 除了起点和终点,最短路的图中的每个城市的费用都要加上. 思 ...
- hdu 1271 整数对
看了别人的解题报告a了, 大致思路就是 A=a+b*10^k+c*10^(k+1) B=a+c*10^k (在A中取出一位数后) N=A+B=2*a+b*10^k+11*c*10^k 这样就好做了,再 ...
- [hackerrank]Manasa and Stones
https://www.hackerrank.com/contests/w2/challenges/manasa-and-stones 简单题. #include<iostream> us ...
- 【mongoDB高级篇①】聚集运算之group,aggregate
group 语法 db.collection.group({ key:{field:1},//按什么字段进行分组 initial:{count:0},//进行分组前变量初始化,该处声明的变量可以在以下 ...
- Hadoop基础教程之搭建开发环境及编写Hello World
整个Hadoop是基于Java开发的,所以要开发Hadoop相应的程序就得用JAVA.在linux下开发JAVA还数eclipse方便. 1.下载 进入官网:http://eclipse.org/do ...
- Linux资源监控命令/工具(网络)
1.手动/自动设定与启动/关闭IP参数:ifconfig,ifup,ifdown 这三个指令的用途都是在启动网络接口,不过,ifup与ifdown仅能就/etc/sysconfig/netw ...