`
Simone_chou
  • 浏览: 192580 次
  • 性别: Icon_minigender_2
  • 来自: 广州
社区版块
存档分类
最新评论

Atlantis(线段树 + 扫描线 + 离散化)

 
阅读更多
Atlantis
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 16991   Accepted: 6479

Description

There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some of these texts even include maps of parts of the island. But unfortunately, these maps describe different regions of Atlantis. Your friend Bill has to know the total area for which maps exist. You (unwisely) volunteered to write a program that calculates this quantity.

Input

The input consists of several test cases. Each test case starts with a line containing a single integer n (1 <= n <= 100) of available maps. The n following lines describe one map each. Each of these lines contains four numbers x1;y1;x2;y2 (0 <= x1 < x2 <= 100000;0 <= y1 < y2 <= 100000), not necessarily integers. The values (x1; y1) and (x2;y2) are the coordinates of the top-left resp. bottom-right corner of the mapped area.
The input file is terminated by a line containing a single 0. Don't process it.

Output

For each test case, your program should output one section. The first line of each section must be "Test case #k", where k is the number of the test case (starting with 1). The second one must be "Total explored area: a", where a is the total explored area (i.e. the area of the union of all rectangles in this test case), printed exact to two digits to the right of the decimal point. 
Output a blank line after each test case.

Sample Input

2
10 10 20 20
15 15 25 25.5
0

Sample Output

Test case #1
Total explored area: 180.00 

 

       题意:

       给出 N (1 ~ 100),代表有 N 个矩形,后给出 N 个矩形的左下坐标值和右上坐标值,输出所有矩形所覆盖的面积和,面积和输出两位小数。直到输出 N = 0 结束。

 

       思路:

       线段树 + 扫描线 + 离散化。过程和求周长和类似,但是面积和就更简单了,不用保存覆盖的端点个数和区间左右端点的覆盖情况,因为面积完全只由长和宽决定,所以维护覆盖的长度和就好,并且统计的时候不用记录上一次的长度值,每次查询后再插入就行了。记得长度是浮点型的。

 

        AC:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>

using namespace std;

const int MAX = 200000;

typedef struct {
        double x, y1, y2;
        int temp;
} node;

node line[105 * 2];
double yy[105 * 2];

double len[MAX * 3];
int cover[MAX * 3];

bool cmp(node a, node b) {
        if (a.x != b.x) return a.x < b.x;
        return a.temp > b.temp;
}

void push_up(int node, int l, int r) {
        if (cover[node]) len[node] = yy[r] - yy[l];
        else if (r - l == 1) len[node] =  0;
        else len[node] = len[node << 1] + len[node << 1 | 1];
}

void build (int node, int l, int r) {
        if (r - l == 1) {
                len[node] = 0;
        } else {
                int mid = (r + l) >> 1;
                build(node << 1, l, mid);
                build(node << 1 | 1, mid, r);
                push_up(node, l, r);
        }
}

void updata (int node, int l, int r, int cl, int cr, int c) {
        if (cl > r || cr < l) return;
        if (cl <= l && cr >= r) {
                cover[node] += c;
                push_up(node, l, r);
                return;
        }
        if (r - l == 1) return;

        int mid = (r + l) >> 1;
        updata(node << 1, l, mid, cl, cr, c);
        updata(node << 1 | 1, mid, r, cl, cr, c);
        push_up(node, l, r);
}

int main() {
        int n, t = 0;

        while (~scanf("%d", &n) && n) {
                int ans = 0, m = 0;

                while (n--) {
                        double x1, y1, x2, y2;
                        scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
                        line[ans].x = x1;
                        line[ans].y1 = y1;
                        line[ans].y2 = y2;
                        line[ans++].temp = 1;

                        line[ans].x = x2;
                        line[ans].y1 = y1;
                        line[ans].y2 = y2;
                        line[ans++].temp = -1;

                        yy[m++] = y1;
                        yy[m++] = y2;
                }

                sort(yy, yy + m);
                m = unique(yy, yy + m) - yy;

                sort(line, line + ans, cmp);
                build(1, 0, ans - 1);

                double res = 0;
                for (int i = 0; i < ans; ++i) {
                        int ll = lower_bound(yy, yy + m, line[i].y1) - yy;
                        int rr = lower_bound(yy, yy + m, line[i].y2) - yy;
                        if (i) {
                                double x, y;
                                x = line[i].x - line[i - 1].x;
                                y = len[1];
                                res += x * y;
                        }
                        updata(1, 0, ans - 1, ll, rr, line[i].temp);
                }

                printf("Test case #%d\n", ++t);
                printf("Total explored area: %.2lf\n\n", res);
        }

        return 0;
}

 

分享到:
评论

相关推荐

    线段树汇总

    - Atlantis(1151):经典的扫描线求矩形面积交,通过离散化和线段树实现。 - Picture(1177):要求求解矩形周长的并,需要维护线段树中的多个信息。 - K-th Number(2155):使用线段树维护归并排序树,并采用...

    Atlantis解题报告

    在本篇解题报告中,我们将深入探讨"Atlantis"这一题目,重点解析其涉及到的线段树(Segment Tree)和离散化(Discretization)技术。线段树是数据结构中的一个重要工具,用于高效地处理区间或段上的查询与更新操作。...

    Atlantis

    Atlantis是一款广受欢迎的字体,尤其在设计领域中被广泛应用。这款字体以其独特的风格和可读性而闻名,为各种创意项目提供了丰富的视觉效果。在本文中,我们将深入探讨 Atlantis 字体的特性、应用场景以及如何在不同...

    pku1151.rar_Atlantis_pku 11_poj Atlant_poj Atlantis_poj11

    描述中提到的“POJ1151 Atlantis的源代码,非常经典线段树应用的题目,求面积。”揭示了问题的核心内容。这是一个涉及到线段树数据结构的编程问题,目标是计算某个区域的面积,可能是在二维平面上。线段树是一种高效...

    Atlantis:一个基于DDD+CQS+GRPC+RabbitMQ快速开发框架

    Atlantis - 一个DDD+CQS+Grpc+RabbitMQ的快速开发框架 框架采用了 DDD 理论模型开发,其中分C端(写端)和Q端(读端)两个部分。C端使用DDD,Q端直接使用数据库,其目的是为了严谨对写的操作,而Q端作为查询需要快速...

    文字处理软件(Atlantis Word Processor) v3.2.13.7.zip

    Atlantis Word Processor是一款简单好用的文字处理软件。软件功能强大,支持读取并编辑*.rtf *.doc *.docx *.cod *.txt等数种格式的文档,支持命令行,,并且软件的界面可以按照你的意愿自定义。Atlantis Word ...

    The Rise Of Atlantis 含破解檔

    非常著名的消消樂遊戲,遊戲畫面精緻華麗,關卡多,難度會依過關次數依序增加,內含破解檔,安裝後將破解檔直接覆蓋原檔案即可。

    Atlantis mf

    Atlantis mf

    java+selenium+maven+testng自动化测试框架实例(实际项目)

    Java+Selenium+Maven+TestNG自动化测试框架是现代软件开发中的一个重要组成部分,尤其是在Web应用程序的质量保证阶段。这个实例项目展示了如何将这四个强大的工具集成为一套完整的自动化测试解决方案。 **Java**: ...

    terragrunt-atlantis-config:为Terragrunt项目生成Atlantis配置

    是用于Terraform拉取请求自动化的强大工具。 每个仓库都可以有一个YAML配置文件,该文件定义了Terraform模块的依赖关系,因此影响依赖模块的PR将自动为这些模块生成Terraform terraform plan 。 是一个Terraform...

    Atlantis Talker-开源

    它不仅提供了基本的文字聊天功能,还具备了留言板、邮件系统、游戏以及多房间等多元化交互体验,所有的这些功能都是通过纯ASCII字符来实现的,展现了ASCII艺术在交互设计中的魅力。 在telnet技术的基础上,Atlantis...

    atlantis:一个强大的iOS小框架,可拦截HTTPHTTPS流量

    通过CocoaPod或SPM安装Atlantis,然后启动Atlantis 默认情况下,Bonjour服务将尝试连接同一网络中的所有Proxyman应用程序: 如果只有一台具有Proxyman的MacOS计算机。 让我们使用简单的版本: import Atlantis //...

    quar_2_atlantis.zip

    Atlantis Lite是一款基于Bootstrap框架构建的高质量后台管理系统模板,其特色在于采用了蓝色调的界面设计,营造出清新、专业的氛围,适合各类企业级应用的后台管理界面。"quar_2_atlantis.zip"这个压缩包包含了完整...

    Stargate Atlantis Model Pack-开源

    《Stargate Atlantis模型包:开源创新的力量》 在虚拟世界构建中,资源与素材的丰富程度直接影响着玩家的沉浸体验。"Stargate Atlantis Model Pack"正是一款为Garry Mod爱好者精心打造的开源模型和材质集合,它将...

    django-dashboard-atlantis-dark:Django仪表板-Atlantis Lite(深色版)| 应用种子

    Atlantis Lite(深色设计)是一个免费的bootstrap 4管理仪表盘,其设计精美,美观,可以显示各种指标,数字或数据可视化。 Atlantis Lite管理仪表盘具有2种布局,许多插件和UI组件,可帮助开发人员快速有效地创建...

    terraform-aws-ecs-atlantis:用于将Atlantis部署为ECS任务的Terraform模块

    Terras-aws-ecs-atlantis 用于将部署到AWS ECS集群的Terraform模块。 该项目是我们针对DevOps的全面方法的一部分。 它是100%开源的,并根据许可。 从字面上看,我们有,它们都是开源的并且维护良好。 去看一下...

    PyPI 官网下载 | atlantis-2021.7.21.tar.gz

    Atlantis 是一个与标题 "PyPI 官网下载 | atlantis-2021.7.21.tar.gz" 相关的 Python 库,它可以从 Python 的官方软件包索引(PyPI)上获取。这个压缩包文件 "atlantis-2021.7.21.tar.gz" 包含了 Atlantis 库的特定...

    atlantis示例:一个简单的terraform项目,可与atlantis引导程序模式一起使用

    一个与atlantis testdrive一起使用的简单terraform项目。 笔记 请不要为此仓库创建拉取请求以测试亚特兰蒂斯。 请按照以下说明操作: : 。 亚特兰蒂斯testdrive模式将为您完成所有艰苦的工作:)

    flask-dashboard-atlantis:Flask Atlantis Lite-开源Flask Seed项目| 应用种子

    Atlantis Lite是一个免费的bootstrap 4管理仪表盘,其设计精美,优雅,可以显示各种指标,数字或数据可视化。 Atlantis Lite管理仪表盘具有2种布局,许多插件和UI组件,可帮助开发人员快速有效地创建仪表盘,从而...

Global site tag (gtag.js) - Google Analytics