hdu 1255 覆盖的面积 线段树扫描线求重叠面积

稀里糊涂打完了没想到1A了,心情还是很舒畅的,c和c++的四舍五入还是四舍六入遇积进位遇偶舍,我感觉很混乱啊,这道题我输出的答案是7.62,也就是遇偶舍了,可是我就手动处理一下进位问题,发现0.005 系统自动进位0.01了,尼玛啊,我一下子就混乱了,不是遇偶舍么,0也是偶数啊,怎么就进位了呢。最后我就不手动处理进位问题了,直接0.2lf%,虽然我输出的结果是7.62,但是提交也过了

这道题和poj1151,hdu1542差不多,扫描线详细讲解http://blog.csdn.net/youngyangyang04/article/details/7787693但是这个是求重叠的面积,需要处理的细节还是挺多的,我有单独写了一个求和函数sum,因为放在insert里面求和会遇到很多问题啊,还有就是离散花的时候也会遇到各种问题,总之要细心啊

#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
#define N 3000
struct Node{
	double y1,y2,x;//x 轴上对应两个y直
	int flag;//标记入度还是出度,入度为1,出度为-1
}node[N];
bool cmp(Node a,Node b){
	return a.x-b.x<0.0000000001;
}
struct node{
	int l,r,s;//s表示度的数,也就是有几条边覆盖
	double ml,mr,len;//len表示度》=2的边的长度
}a[N*3];
double y[N];
void build(int left,int right,int i){
	a[i].l=left;
	a[i].r=right;
	a[i].ml=y[left];//离散化的
	a[i].mr=y[right];
	a[i].s=0;
	if((a[i].r-a[i].l)==1)
		return ;
	int mid=(a[i].l+a[i].r)>>1;
	build(a[i].l,mid,i*2);
	build(mid,a[i].r,i*2+1);
}
void insert(Node b,int i){
	if(a[i].ml==b.y1&&a[i].mr==b.y2){//如果找到这条边就加上这条边的度<span style="font-family: Arial, Helvetica, sans-serif;">b.flag,度表示有几条边覆盖</span>
		a[i].s+=b.flag;
		return ;
	}
	if(a[i].s!=0){//向下拓展,这一步很重要
		a[i*2].s+=a[i].s;
		a[i*2+1].s+=a[i].s;
		a[i].s=0;
	}
	int mid=(a[i].r+a[i].l)>>1;
	if(b.y2<=y[mid]) insert(b,i*2);
	else if(b.y1>=y[mid]) insert(b,i*2+1);
	else{
		Node temp=b;
		temp.y2=y[mid];
		insert(temp,i*2);
		temp=b;
		temp.y1=y[mid];
		insert(temp,i*2+1);
	}
}
void sum(int i){
	if(a[i].r-a[i].l==1){
		if(a[i].s>=2)
			a[i].len=a[i].mr-a[i].ml;
		else
			a[i].len=0;
		return;
	}
	if(a[i].s!=0){
		a[i*2].s+=a[i].s;
		a[i*2+1].s+=a[i].s;
		a[i].s=0;
	}
	sum(i*2);
	sum(i*2+1);
	a[i].len=a[i*2].len+a[i*2+1].len;//求出該边度>=2的长度
}
int main(){
	int t,n;
	double x1,x2,y1,y2;
	scanf("%d",&t);
	while(t--){
		int cou=1;
		scanf("%d",&n);
		while(n--){
			scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
			node[cou].x=x1;
			node[cou].y1=y1;
			node[cou].y2=y2;
			node[cou].flag=1;
			y[cou++]=y1;
			node[cou].x=x2;
			node[cou].y1=y1;
			node[cou].y2=y2;
			node[cou].flag=-1;
			y[cou++]=y2;
		}
		sort(y+1,y+cou);
		sort(node+1,node+cou,cmp);
		build(1,cou-1,1);
		double ans=0;
		insert(node[1],1);
		sum(1);
		for(int i=2;i<cou;i++){
			ans+=a[1].len*(node[i].x-node[i-1].x);
			insert(node[i],1);
			sum(1);
		}
		printf("%.2lf\n",ans);

	}
}

hdu 1255 覆盖的面积 线段树扫描线求重叠面积

时间: 2024-12-09 11:23:24

hdu 1255 覆盖的面积 线段树扫描线求重叠面积的相关文章

线段树+扫描线求矩形面积的并

POJ 1151 Atlantis(线段树+扫描线) 参考博客https://blog.csdn.net/lwt36/article/details/48908031 上面博客的原理讲解非常清楚 在这我只对代码的模板分层讲解 一些基础的 #include <iostream> #include <cstdio> #include <string.h> #include <algorithm> #include <cmath> #define ls

HDU 4419 Colourful Rectangle --离散化+线段树扫描线

题意: 有三种颜色的矩形n个,不同颜色的矩形重叠会生成不同的颜色,总共有R,G,B,RG,RB,GB,RGB 7种颜色,问7种颜色每种颜色的面积. 解法: 很容易想到线段树扫描线求矩形面积并,但是如何维护每种颜色的长度着实让我伤透了脑筋.后来看了一位朋友的题解,才幡然醒悟. 开始想到了用二进制表示颜色,R用001表示,G用010表示,B用100表示.那么就可以用十进制1~7表示7种不同颜色了. 维护 cov[rt][1~3] 表示此区间内3种原色各有多少个, Len[rt][i]表示每种颜色的长

hdu 1255 覆盖的面积(线段树&amp;扫描线&amp;重复面积)

覆盖的面积 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3375    Accepted Submission(s): 1645 Problem Description 给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. Input 输入数据的第一行是一个正整数T(1<=T<=100),代表测试数据的数量.每个测试数

HDU 1264 Counting Squares (线段树-扫描线-矩形面积并)

Problem A : Counting Squares From:HDU, 1264 Problem Description Your input is a series of rectangles, one per line. Each rectangle is specified as two points(X,Y) that specify the opposite corners of a rectangle. All coordinates will be integers in t

HDU 3642 Get The Treasury 线段树+扫描线

反向标记是错的,要对矩形进行拆分 #include <cstdio> #include <algorithm> #include <cstring> #include <vector> typedef long long LL; using namespace std; #define lson rt << 1,l,mid #define rson rt << 1 | 1,mid + 1,r const int maxn = 5e4

线段树 : 求矩形面积的并 ---- hnu : 12884 Area Coverage

Area Coverage Time Limit: 10000ms, Special Time Limit:2500ms, Memory Limit:65536KB Total submit users: 16, Accepted users: 12 Problem 12884 : No special judgement Problem description In this day and age, a lot of the spying on other countries is done

hdu1255 覆盖的面积 线段树-扫描线

矩形面积并 线段树-扫描线裸题 1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #include<math.h> 5 using namespace std; 6 const int maxm=2e3+5; 7 const double eps=1e-5; 8 9 struct seg{ 10 double x,y1,y2; 11 int c; 12 bool operator

HDU 1255 覆盖的面积 (线段树+扫描线+离散化)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1255 题意很清楚,就是让你求矩阵之间叠加层数大于1的矩形块的面积和. 因为n只有1000,所以我离散化一下,数据大小就缩小了,那么之后只需要线段树单点更新就好了. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <map> 5 #include <algor

HDU 1255 覆盖的面积(线段树扫描线求面积的交)

Problem Description 给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. Input 输入数据的第一行是一个正整数T(1<=T<=100),代表测试数据的数量.每个测试数据的第一行是一个正整数N(1<=N<=1000),代表矩形的数量,然后是N行数据,每一行包含四个浮点数,代表平面上的一个矩形的左上角坐标和右下角坐标,矩形的上下边和X轴平行,左右边和Y轴平行.坐标的范围从0到100000. 注意:本题的输入数据较多,推荐使用scanf读入数据. Out