[codevs3044][POJ1151]矩形面积求并
[codevs3044][POJ1151]矩形面积求并
试题描述
输入
可能有多组数据,读到n=0为止(不超过15组)
每组数据第一行一个数n,表示矩形个数(n<=100)
接下来n行每行4个实数x1,y1,x2,y1(0 <= x1 < x2 <= 100000;0 <= y1 < y2 <= 100000),表示矩形的左下角坐标和右上角坐标
输出
每组数据输出一行表示答案
输入示例
25.5
输出示例
180.00
数据规模及约定
见“输入”
题解
扫描线 + 线段树。
线段树标记永久化,因为这题每个时刻只需要知道线段树根节点的信息,而不是每次查询一段区间,所以很容易实现,具体见代码,或者黄学长的题解。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <cmath>
using namespace std; int read() {
int x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
return x * f;
} #define maxn 110 struct Line {
int l, r, h, tp;
Line() {}
Line(int _1, int _2, int _3, int _4): l(_1), r(_2), h(_3), tp(_4) {}
bool operator < (const Line& t) const { return h < t.h; }
} ls[maxn<<1];
double posx[maxn<<1], posy[maxn<<1], numx[maxn<<1], numy[maxn<<1], ans; int cntv[maxn<<3];
double sumv[maxn<<3];
void maintain(int L, int R, int o) {
int lc = o << 1, rc = lc | 1;
if(cntv[o]) sumv[o] = numx[R] - numx[L-1];
else if(L == R) sumv[o] = 0;
else sumv[o] = sumv[lc] + sumv[rc];
return ;
}
void update(int L, int R, int o, int ql, int qr, int v) {
if(ql <= L && R <= qr) {
cntv[o] += v;
return maintain(L, R, o);
}
int M = L + R >> 1, lc = o << 1, rc = lc | 1;
if(ql <= M) update(L, M, lc, ql, qr, v);
if(qr > M) update(M+1, R, rc, ql, qr, v);
return maintain(L, R, o);
} int main() {
while(1) {
int n = read(), cntx = 0, cnty = 0, cntl = 0;
if(!n) break;
for(int i = 1; i <= n; i++) {
double x1, x2, y1, y2;
scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
posx[++cntx] = x1; posx[++cntx] = x2;
posy[++cnty] = y1; posy[++cnty] = y2;
numx[cntx-1] = posx[cntx-1]; numx[cntx] = posx[cntx];
numy[cnty-1] = posy[cnty-1]; numy[cnty] = posy[cnty];
} sort(numx + 1, numx + cntx + 1);
sort(numy + 1, numy + cnty + 1);
for(int i = 1; i <= n; i++) {
int x1, x2, y1, y2;
x1 = lower_bound(numx + 1, numx + cntx + 1, posx[(i<<1)-1]) - numx;
x2 = lower_bound(numx + 1, numx + cntx + 1, posx[i<<1]) - numx;
y1 = lower_bound(numy + 1, numy + cnty + 1, posy[(i<<1)-1]) - numy;
y2 = lower_bound(numy + 1, numy + cnty + 1, posy[i<<1]) - numy;
ls[++cntl] = Line(x1, x2, y1, 1);
ls[++cntl] = Line(x1, x2, y2, -1);
}
sort(ls + 1, ls + cntl + 1); memset(cntv, 0, sizeof(cntv));
memset(sumv, 0, sizeof(sumv));
ans = 0;
double start = numx[1];
for(int i = 1; i < cntx; i++) numx[i] = numx[i+1] - start;
for(int i = 1; i < cntl; i++) {
if(ls[i].l < ls[i].r) update(1, cntx - 1, 1, ls[i].l, ls[i].r - 1, ls[i].tp);
ans += (numy[ls[i+1].h] - numy[ls[i].h]) * sumv[1];
} printf("%.2lf\n", ans);
} return 0;
}
注意:POJ 上输出格式不太一样,详见题面。
[codevs3044][POJ1151]矩形面积求并的更多相关文章
- codves 3044 矩形面积求并
codves 3044 矩形面积求并 题目等级 : 钻石 Diamond 题目描述 Description 输入n个矩形,求他们总共占地面积(也就是求一下面积的并) 输入描述 Input Desc ...
- poj-1151矩形面积并-线段树
title: poj-1151矩形面积并-线段树 date: 2018-10-30 22:35:11 tags: acm 刷题 categoties: ACM-线段树 概述 线段树问题里的另一个问题, ...
- codevs 3044 矩形面积求并
3044 矩形面积求并 题目描述 Description 输入n个矩形,求他们总共占地面积(也就是求一下面积的并) 输入描述 Input Description 可能有多组数据,读到n=0为止(不 ...
- [Codevs] 矩形面积求并
http://codevs.cn/problem/3044/ 线段树扫描线矩形面积求并 基本思路就是将每个矩形的长(平行于x轴的边)投影到线段树上 下边+1,上边-1: 然后根据线段树的权值和与相邻两 ...
- [codevs3044]矩形面积求并
题目描述 Description 输入n个矩形,求他们总共占地面积(也就是求一下面积的并) 输入描述 Input Description 可能有多组数据,读到n=0为止(不超过15组) 每组数据第一行 ...
- 3044 矩形面积求并 - Wikioi
题目描述 Description 输入n个矩形,求他们总共占地面积(也就是求一下面积的并) 输入描述 Input Description 可能有多组数据,读到n=0为止(不超过15组) 每组数据第一行 ...
- POJ 1151 Atlantis 矩形面积求交/线段树扫描线
Atlantis 题目连接 http://poj.org/problem?id=1151 Description here are several ancient Greek texts that c ...
- 矩形面积求并(codevs 3044)
题目描述 Description 输入n个矩形,求他们总共占地面积(也就是求一下面积的并) 输入描述 Input Description 可能有多组数据,读到n=0为止(不超过15组) 每组数据第一行 ...
- poj1151==codevs 3044 矩形面积求并
Atlantis Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 21511 Accepted: 8110 Descrip ...
随机推荐
- 转】upstart封装mongodb应用为系统服务
原博文出自于: http://blog.fens.me/category/%E6%95%B0%E6%8D%AE%E5%BA%93/page/4/ 感谢! upstart封装mongodb应用为系统服务 ...
- 12.1Java-构造方法
一.构造方法 作用:在new的同时对成员变量赋值,给对象的属性初始化赋值格式:权限 方法名(参数列表){}方法的名字,必须和类的名字完全一致,大小写一致构造方法不许写返回值类型,如void,int 构 ...
- SpringBoot之旅第七篇-Docker
一.引言 记得上大三时,要给微机房电脑安装系统,除了原生的操作系统外,还要另外安装一些必要的开发软件,如果每台电脑都重新去安装的话工作量就很大了,这个时候就使用了windows镜像系统,我们将要安装的 ...
- poj3109 Inner Vertices
思路: 树状数组 + 扫描线. 实现: #include <cstdio> #include <vector> #include <algorithm> using ...
- 安卓(Android)关于 RecyclerView 不能填充满宽度
RecyclerView 不能填充满屏幕宽度 RecyclerView 的 Adapter 在使用是,一定要 @Overridepublic RecyclerView.ViewHolder onCre ...
- Farseer.net轻量级开源框架 中级篇:BasePage、BaseController、BaseHandler、BaseMasterPage、BaseControls基类使用
导航 目 录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 中级篇: UrlRewriter 地址重写 下一篇:Farseer.net轻量级开源框架 中 ...
- 批处理 reg add /?
C:\Users\Administrator>reg add /? REG ADD KeyName [/v ValueName | /ve] [/t Type] [/s Separator] [ ...
- Linux下 SpringBoot jar项目后台运行、查看、停用
运行java jar: nohup java -jar **-0.0.1-SNAPSHOT.jar & 查看进程: 采用top或者ps aux命令.一般 如果后台是springboot,jar ...
- mfc 菜单
创建一个基于对话框的工程,工程名为CreateMenu 为该对话框增加一个文件菜单项和测试菜单项,如下图所示 测试菜单项至少要有一个子菜单项 在对话框属性中关联该菜单 在resource.h中增加 ...
- CAD绘制二维码(网页版)
js中实现代码说明: //新建一个COM组件对象 参数为COM组件类名 var getPt = mxOcx.NewComObject("IMxDrawUiPrPoint"); ge ...