题面

二维平面中,给定 \(N\) 个等腰直角三角形(每个三角形的两条直角边分别平行于坐标轴,斜边从左上到右下)。我们用三个非负整数 \((x, y, d)\) 来描述这样一个三角形,三角形三个顶点的坐标分别为 \((x, y), (x + d, y)\) 和 \((x, y + d)\) 。要求计算这 \(N\) 个三角形所覆盖的总面积。例如,下图有 \(3\) 个三角形,覆盖的总面积为 11.0。

输入格式:

输入文件第一行为一个正整数N,表示三角形的个数。

接下来的 \(N\) 行每行有用空格隔开的三个非负整数,\(x, y, d\) ,描述一个三角形的顶点坐标,分别为 \((x, y)\) , \((x + d, y)\) , \(( x, y+d)\) ,其中 \(x, y, d\) 满足 \(0<= x, y, d<=1000000\) 。

输出格式:

仅包含一行,为一个实数 \(S\) ,表示所有三角形所覆盖的总面积,输出恰好保留一位小数。输入数据保证 \(S\le 2^{31}\) 。

输入样例

3
1 1 4
2 0 2
3 2 2

输出样例

11.0

\(Solution:\)

显然扫描线,扫描线的做法因题而异,不同的题面有不同的写法。

这里给出链表+扫描线的方法:

先按 \(y\) 轴排序,然后从下扫描到上,因为坐标都是小于1e6的,所以直接暴力扫。

这题跟矩形面积并不一样,因为是等腰直角三角形,每次扫描线向上走一个单位,扫描线对应的地方覆盖就要少一。

数据结构:

  1. 双向链表

实际上是一个容器,存的是覆盖当前扫描线的三角形的编号,即如果编号为 \(i\) 的三角形覆盖了扫描线的一部分,那么 \(list[i]\) 就在链表中。

链表只是为了我们快速修改信息,插入和删除都是 \(O(1)\) 的, 查询信息也很方便。

  1. \(cover[x]\)

存储 ( \(x\) , 扫描线位置) 被多少个三角形覆盖,用来更新扫描线被覆盖的线段长度用。

算法流程:

  1. 按 \(y\) 轴排序。
  2. 从下往上扫描 \(i\) 记录扫描线的位置,\(j\) 记录当前有前 \(j\) 个在链表中或者已经处理完。
  3. 先统计链表中的答案 \(now\) ,并修改信息,记下 \(i-1\) 时的覆盖线段长,\(ans+= \frac{now+last}{2}\).
  4. 将新的三角形插进链表,更新 \(cover\) ,求出新的被覆盖线段长,记录到 \(last\) ,扫描线上移,执行 \(3\) 直至扫描完成。
#include <iostream>
#include <cstdio>
#include <algorithm> using namespace std; const int N = 1e5 + 20; int n, mx;
struct Tri
{
int x, y, d, l, r; Tri() {}
Tri(const int &_x, const int &_y, const int &_d)
{ x = _x, y = _y, d = _d, l = _x, r = _x + _d - 1;} } tri[N];
inline bool cmp(const Tri &A, const Tri &B)
{ return A.y < B.y; } namespace List
{
int head, tail, nxt[N], pre[N]; void Del(int x)
{
pre[nxt[x]] = pre[x];
nxt[pre[x]] = nxt[x];
} void Ins(int x, int y)
{
pre[nxt[x]] = y;
nxt[y] = nxt[x];
nxt[x] = y;
pre[y] = x;
} bool ins(int x)
{
if (tri[x].d == 0) return false;
Ins(head, x);
return true;
}
}
using namespace List; int cover[(int)2e6 + 2]; int main()
{ cin >> n;
for (int i = 1; i <= n; ++ i)
{
int x, y, d;
cin >> x >> y >> d;
mx = max(mx, y + d);
tri[i] = Tri(x, y, d);
}
sort(tri + 1, tri + 1 + n, cmp); head = 0; tail = n + 1;
nxt[head] = tail; pre[tail] = head;
int ans = 0, last = 0, now = 0;
for (int i = tri[1].y, j = 1; i <= mx; ++ i)
{
now = last;
for (int k = nxt[head]; k != tail; k = nxt[k])
{
-- cover[tri[k].r];
if (!cover[tri[k].r]) now--;
tri[k].r --;
if (tri[k].x > tri[k].r) Del(k);
}
ans += now + last;
while (j <= n && tri[j].y == i)
{
if (ins(j))
{
for (int k = tri[j].x; k < tri[j].x + tri[j].d; k ++)
{
if (!cover[k]) now ++;
cover[k] ++;
}
}
j ++;
}
last = now;
}
printf("%.1f\n", ans / 2.0);
}

[HNOI2012]三角形覆盖问题的更多相关文章

  1. BZOJ 2731 Luogu P3219 [HNOI2012]三角形覆盖问题 (扫描线)

    题目链接: (bzoj)https://www.lydsy.com/JudgeOnline/problem.php?id=2731 (luogu)https://www.luogu.org/probl ...

  2. 【题解】三角形 [P1222] / 三角形覆盖问题 [HNOI2012] [P3219]

    [题解]三角形 [P1222] / 三角形覆盖问题 [HNOI2012] [P3219] 传送门: 三角形 \(\text{[P1222]}\) 三角形覆盖问题 \(\text{[HNOI2012] ...

  3. 【BZOJ2731】三角形覆盖问题

    想象一条平行于\(y\)轴的扫描线,从低往高扫描.如何确定关键高度才能使每两个关键高度之间分割出的图形易于计算呢? 关键高度有:三角形底边高度.三角形上顶点高度.三角形交点的高度. ​ 如此分割,我们 ...

  4. [HNOI 2012]三角形覆盖问题

    Description 二维平面中,给定   N个等腰直角三角形(每个三角形的两条直角边分别     平行于坐标轴,斜边从左上到右下).我们用三个非负整数( x, y, d)来描   述这样一个三角形 ...

  5. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  6. css实现的透明三角形

    css实现下图样式,具体像素值记不住了,很好设置,html code (2014百度秋招面试题): <div id="demo"></div>   分析:这 ...

  7. 现代3D图形编程学习-设置三角形颜色(译)

    本书系列 现代3D图形变成学习 http://www.cnblogs.com/grass-and-moon/category/920962.html 设置颜色 这一章会对上一章中绘制的三角形进行颜色的 ...

  8. HihoCoder1642 : 三角形面积和([Offer收割]编程练习赛37)(求面积)(扫描线||暴力)(占位)

    描述 如下图所示,在X轴上方一共有N个等腰直角三角形.这些三角形的斜边与X轴重合,斜边的对顶点坐标是(Xi, Yi). (11,5) (4,4) /\ /\(7,3) \ / \/\/ \ / /\/ ...

  9. HihoCoder1652 : 三角形面积和2([Offer收割]编程练习赛38)(几何)(不会几何,占位)

    描述 如下图所示,在X轴上方一共有N个三角形.这些三角形的底边与X轴重合,底边上两个顶点的坐标分别是(Li, 0)和(Ri, 0),底边的对顶点坐标是(Xi, Yi).其中Li ≤ Xi ≤ Ri 且 ...

随机推荐

  1. T4Toolbox简单了解

    使用T4模板,最令人喜欢的就是T4Toolbox了,他可以帮助我们生成多文件,并且直接包含在项目中. 环境:vs2017 T4代码高亮插件:Devart T4 Editor 插件地址:T4 Toolb ...

  2. unity3D引擎:2D游戏自动瞄准算法实现

    转:http://blog.csdn.net/naitu/article/details/39555373 在很多飞行射击类游戏里,都有敌人向玩家自动瞄准并开火的功能.在这里本人用unity3D引擎新 ...

  3. MySQL的数据类型(二)

    MySQL中提供了多种对字符数据的存储类型,不同的版本可能有所差异.以5.0版本为例,MySQL包括了CHAR.VARCHAR.BINARY.VARBINARY.BLOB.TEXT等多种字符串类型. ...

  4. MySql外键建立在哪里(更新)

    一对一的时候:分为主表和附表  外键建立在附件上  附表的外键关联到主表的主键上,Example:学生表和学生信息表,在学生信息表上建立外键 一对多的时候:分为一和多  外键建立在多上  Exampl ...

  5. jQuery 打气球小游戏 点击气球爆炸效果

    最近在学习前端,看到偶尔看到前端小游戏,就想自己写一个小游戏,奈何水平有限,只能写打气球这种简单的,所有的气球都是动态生成的,气球的颜色也是随机的 html部分 <div class=" ...

  6. javaScript函数封装

    本篇封装了一些常用的函数,兼容IE8及以下的浏览器,怪异模式. 按需加载loadScript().绑定事件处理函数addEvet().查看滚动尺寸getScrollOffset().查看可视区窗口尺寸 ...

  7. Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO

    你有碰上过这样的提示吗? Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in t ...

  8. Symfony FOSUserBundle用户登录验证

    symfony是一个由组件构成的框架,登录验证的也是由一些组件构成,下面就介绍一下FOSUserBundle的使用. 以symfony 3.3为例, 首先我们需要先安装一下FOSUserBundle. ...

  9. NOIP模拟 candy

    题目描述 一天,小 DD 决定买一些糖果.他决定在两家不同的商店中买糖果,来体验更多的口味. 在每家商店中都有 nn 颗糖果,每颗糖果都有一个权值:愉悦度,代表小 DD 觉得这种糖果有多好吃.其中,第 ...

  10. Centos7 搭建 hadoop3.1.1 集群教程

    配置环境要求: Centos7 jdk 8 Vmware 14 pro hadoop 3.1.1 Hadoop下载 安装4台虚拟机,如图所示 克隆之后需要更改网卡选项,ip,mac地址,uuid 重启 ...