扫面线+线段树(hdu1542)
之前写过这个算法,时间长了就忘掉了,,现在不看书自己努力回想起来,对算法的理解,对线段树的理解感觉也更深了一点(可能心理作用,哈哈哈)
思路简单说一下吧
从做到右遍历每一条矩阵的边(左右边),看该边对右边的面积贡献是正还是负(矩阵左边为正,右边为负),在y轴上用线段树维护在y轴的贡献值,与x轴上该边与下一条边的差值相乘即可
// acm1.cpp: 定义控制台应用程序的入口点。
//
#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
#include<vector>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<set>
#include<map>
#include<fstream>
#include<cstdlib>
#include<ctime>
using namespace std;
typedef long long ll;
typedef long long lint;
const ll mod=1e9+;
const int maxn=1e2+;
const int maxm=1e5+;
const double eps=1e-;
int ar1[maxn],ar2[maxn],m,n;
bool bo[maxn];
struct line{
double y1,y2,x;
int ma;
}li[maxn*]; struct node{
int l,r;
int mark;
double length;
}no[maxn*];
double xl[maxn],yl[maxn];
bool cmp(line l1,line l2){
return l1.x<l2.x;
}
void build(int x,int y,int o){
no[o].l=x;
no[o].r=y;
no[o].length=;
no[o].mark=;
if(y-x==)return ;
int mid=(x+y)>>;
if(mid>x)build(x,mid,o*);
if(mid<y)build(mid,y,o*+);
}
void down(int x){
if(no[x].mark>)no[x].length=yl[no[x].r]-yl[no[x].l];
else if(no[x].r==no[x].l+){
no[x].length=;
}
else{
no[x].length=no[x*].length+no[x*+].length;
}
}
void update(int o,line & liMid){
double func1=yl[no[o].l],func2=yl[no[o].r];
if(liMid.y1<=func1&&liMid.y2>=func2){
no[o].mark+=liMid.ma;
}
else{
double funcMid=yl[(no[o].l+no[o].r)>>];
if(liMid.y1<funcMid)update(o*,liMid);
if(liMid.y2>funcMid)update(o*+,liMid);
}
down(o);
}
int main()
{
int fir=;
while(~scanf("%d",&n)&&n){
for(int i=;i<n;i++){
double x1,x2,y1,y2;
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
li[i*].x=x1;
li[i*].y1=y1;
li[i*].y2=y2;
li[i*].ma=;
li[i*+].x=x2;
li[i*+].y1=y1;
li[i*+].y2=y2;
li[i*+].ma=-;
yl[i*]=y1;
yl[i*+]=y2;
}
sort(li,li+*n,cmp);
sort(yl,yl+*n);
int len=unique(yl,yl+*n)-yl;
build(,len-,);
double ans=;
for(int i=;i<*n-;i++){
update(,li[i]);
ans+=no[].length*(li[i+].x-li[i].x);
}
printf("Test case #%d\nTotal explored area: %.2lf\n\n",++fir,ans);
}
return ;
}
扫面线+线段树(hdu1542)的更多相关文章
- POJ1151-扫面线+线段树+离散化//入门题
比较水的入门题 记录矩形竖边的x坐标,离散化排序.以被标记的边建树. 扫描线段树,查询线段树内被标记的边.遇到矩形的右边就删除此边 每一段的面积是查询结果乘边的横坐标之差,求和就是答案 #includ ...
- 矩阵重叠面积计算 线段树hdu1542
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Su ...
- HDU3333 Turing Tree(线段树)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=3333 Description After inventing Turing Tree, 3x ...
- POJ 2482 Stars in Your Window 线段树扫描线
Stars in Your Window Description Fleeting time does not blur my memory of you. Can it really be 4 ...
- 【hdu1542】线段树求矩形面积并
分割线内容转载自http://hzwer.com/879.html ------------------------------------------------------------------ ...
- hdu1542 矩形面积并(线段树+离散化+扫描线)
题意: 给你n个矩形,输入每个矩形的左上角坐标和右下角坐标. 然后求矩形的总面积.(矩形可能相交). 题解: 前言: 先说说做这道题的感受: 刚看到这道题顿时就懵逼了,几何 烂的渣渣.后来从网上搜题解 ...
- hdu1542 Atlantis (线段树+扫描线+离散化)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- Codeforces Round #291 (Div. 2) D. R2D2 and Droid Army [线段树+线性扫一遍]
传送门 D. R2D2 and Droid Army time limit per test 2 seconds memory limit per test 256 megabytes input s ...
- HDU1542 Atlantis —— 求矩形面积并 线段树 + 扫描线 + 离散化
题目链接:https://vjudge.net/problem/HDU-1542 There are several ancient Greek texts that contain descript ...
随机推荐
- Python 实现随机打乱字符串
from random import shuffle def shuffle_str(s): # 将字符串转换成列表 str_list = list(s) # 调用random模块的shuffle函数 ...
- SQLite3中dos命令下退出"...>"状态的方法
今天在看Android中SQLite,跟着书上一步一步走,在dos中敲命令时候不小心敲错了,命令行就会突然变成”…>”这样的,本来是”sqlite>”的,然后接下来后面的就没办法在继续操作 ...
- mybatis批量添加、批量删除
<!-- 批量添加 --> <insert id="insertNameListSynHisBatch" parameterType="java.uti ...
- 孤荷凌寒自学python第六十三天学习mongoDB的基本操作并进行简单封装2
孤荷凌寒自学python第六十三天学习mongoDB的基本操作并进行简单封装2 (完整学习过程屏幕记录视频地址在文末) 今天是学习mongoDB数据库的第九天. 今天继续学习mongoDB的简单操作, ...
- TensorFlow dataset API 使用
# TensorFlow dataset API 使用 由于本人感兴趣的是自然语言处理,所以下面有关dataset API 的使用偏向于变长数据的处理. 1. 从迭代器中引入数据 import num ...
- 软工实践Alpha冲刺(9/10)
v队名:起床一起肝活队 组长博客:博客链接 作业博客:班级博客本次作业的链接 组员情况 组员1(队长):白晨曦 过去两天完成了哪些任务 描述: 已经解决登录注册等基本功能的界面. 完成非功能的主界面制 ...
- CodeForces C. Maximal Intersection
http://codeforces.com/contest/1029/problem/C You are given nn segments on a number line; each endpoi ...
- JavaScript中的parseInt和Number函数
函数作用: parseInt将字符串(String)类型转为整数类型. Number() 函数把对象(Object)的值转换为数字. 语法不同: parseInt(string, [radix]) s ...
- Tomcat学习笔记(十)
StandardWrapper容器 Context容器包含一个或者多个Wrapper实例,每个Wrapper实例表示一个具体的servlet定义. 方法调用序列 具体过程 (1)连接器创建reques ...
- 《c程序设计语言》读书笔记-5.5-指针实现strncpy,strncat,strncmp
#include <stdio.h> #include <math.h> #include <stdlib.h> #include <string.h> ...