IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> acwing247. 亚特兰蒂斯(扫描,离散化,线段树,二分) -> 正文阅读

[开发测试]acwing247. 亚特兰蒂斯(扫描,离散化,线段树,二分)

有几个古希腊书籍中包含了对传说中的亚特兰蒂斯岛的描述。

其中一些甚至包括岛屿部分地图。

但不幸的是,这些地图描述了亚特兰蒂斯的不同区域。

您的朋友 Bill 必须知道地图的总面积。

你自告奋勇写了一个计算这个总面积的程序。

输入格式

输入包含多组测试用例。

对于每组测试用例,第一行包含整数?nn,表示总的地图数量。

接下来?nn?行,描绘了每张地图,每行包含四个数字?x1,y1,x2,y2x1,y1,x2,y2(不一定是整数),(x1,y1)(x1,y1)?和?(x2,y2)(x2,y2)?分别是地图的左上角位置和右下角位置。

注意,坐标轴?xx?轴从上向下延伸,yy?轴从左向右延伸。

当输入用例?n=0n=0?时,表示输入终止,该用例无需处理。

输出格式

每组测试用例输出两行。

第一行输出?Test case #k,其中?kk?是测试用例的编号,从?11?开始。

第二行输出?Total explored area: a,其中?aa?是总地图面积(即此测试用例中所有矩形的面积并,注意如果一片区域被多个地图包含,则在计算总面积时只计算一次),精确到小数点后两位数。

在每个测试用例后输出一个空行。

数据范围

1≤n≤100001≤n≤10000,
0≤x1<x2≤1000000≤x1<x2≤100000,
0≤y1<y2≤1000000≤y1<y2≤100000
注意,本题?nn?的范围上限加强至?1000010000。

输入样例:

2
10 10 20 20
15 15 25 25.5
0

输出样例:

Test case #1
Total explored area: 180.00 

/*感觉这要没有特殊区间查询,lz标记就不用下放,lz标记用法是真的多*/
#include<stdio.h>
#include<vector>
#include<string.h>
#include<algorithm>
using namespace std;
vector<double > vs;/*从下往上扫描*/
struct line/*用来存直线:把每个矩形的上边跟下边都存成一条条线段*/
{
	double x,y1,y2;/*x是直线的高度,y1,y2是左右端点*/
	int f;/*1表示下边,表示这条边要开始加入,-1结束*/
	bool operator < (const line &t) const
	{
		return x<t.x;
	}
} seg[200100];

struct segtree
{
	int l,r,lz;
	double len;
} tree[201000];

int find(double x)
{
	return lower_bound(vs.begin(),vs.end(),x)-vs.begin();
}

void build(int node,int l,int r)
{
	int mid;
	tree[node]= {l,r,0,0};
	if(l==r)
		return;
	mid=(l+r)/2;
	build(node*2,l,mid);
	build(node*2+1,mid+1,r);
}
void up(int node)
{
	if(tree[node].lz)
	{
		tree[node].len=vs[tree[node].r+1]-vs[tree[node].l];/*当lz!=0那么这条线段还要积分使用*/
		return;
	}
	tree[node].len=tree[node*2].len+tree[node*2+1].len;/*向上级汇报下面一共覆盖的区间长度*/
}

void update(int node,int l,int r,int z)/*主要是求将线段加入或删除,再求总区间覆盖长度*/
{
	if(tree[node].l>=l&&tree[node].r<=r)
	{
		tree[node].lz+=z;/*lz的作用:记录这段区间被覆盖了多少次,一段线段被删除后
		还可能有其他线段在这段区间上的积分没有结束,即当lz!=0那么这条线段还要积分使用*/
		up(node);
		return;
	}

	int mid=(tree[node].l+tree[node].r)/2;

	if(l<=mid) update(node*2,l,r,z);

	if(r>=mid+1) update(node*2+1,l,r,z);

	up(node);
}

int main()
{
	int n,m,j,i,L,R,k=0,zz=1;
	double x1,x2,y1,y2,sum=0.0;
	while(~scanf("%d",&n)&&n)
	{
		vs.clear();
		k=0;
		for(i=1; i<=n; i++)
		{
			scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
			seg[++k]= {x1,y1,y2,1};
			seg[++k]= {x2,y1,y2,-1};
			vs.push_back(y1);
			vs.push_back(y2);
		}
		sort(seg+1,seg+1+k);/*为了从低到高扫描*/

		sort(vs.begin(),vs.end());
		vs.erase(unique(vs.begin(),vs.end()),vs.end());/*对所有的线段的左右端点进行离散查重*/
		m=vs.size();/*把 15 20 25 25.5 离散化成 0 1 2 3 区间长度就是vs[3]-vs[0]*/

		build(1,0,m-2);
		/*建树区间0~(m-2)主要是想用[l,r]要表示区间[l,r+1],因为线段
		长度都是大于0的[3,3]区间是没有意义的*/
		update(1,find(seg[1].y1),find(seg[1].y2)-1,seg[1].f);
		sum=0;

		for(i=2; i<=k; i++)
		{
			L=find(seg[i].y1);/*找到这条线段对应的高度在离散数组中对应的下标*/
			R=find(seg[i].y2)-1;
			sum+=tree[1].len*(seg[i].x-seg[i-1].x);
			update(1,L,R,seg[i].f);/*就是算seg[i-1]~seg[i]参加积分的线段长度有一共有多长*/
		}
		printf("Test case #%d\n",zz++);
		printf("Total explored area: %.2lf\n\n",sum);
	}
	return 0;
}

无标题.png

  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2021-08-26 12:24:47  更:2021-08-26 12:26:10 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/13 5:26:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码