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

传送门:

【题目描述】

给出 \(n\) 个等腰直角三角的顶点和直角边长,求覆盖总面积。

【输入】

第一行一个整数 \(n\),表示三角形个数,接下来 \(n\) 行每行三个整数 \(x,y,m\),分别表示顶点坐标、直角边长(两直角边分别平行于 \(x,y\) 轴且顶点在左下角)。

【输出】

答案保留一位小数。

【样例】

样例输入:
5
-5 -3 6
-1 -2 3
0 0 2
-2 2 1
-4 -1 2 样例输出:
24.5

【数据范围】

\(100 \%:\) \(n \leqslant 2000,\) \(-10^7 \leqslant x,y \leqslant 10^7,\) \(m \leqslant 1000\)【三角形】

\(100 \%:\) \(n \leqslant 10000,\) \(0 \leqslant x,y,m \leqslant 10^6\)【三角形覆盖问题】

【分析】

【计算几何全家桶】

求三角形面积并的板题。

自适应辛普森法乱搞(什么?你说 三角形覆盖问题 用辛普森过不了?啪)。

代码大致和 圆的面积并 相同,只需要改几个关键点即可:

\(F\) 函数中求交线(相较于圆变简单了):

#define LD double
#define Re register int
#define Rd register LD
Re t=0;
for(Re i=1;i<=n;++i)
if(dcmp(Y-C[i].D)>=0&&dcmp(Y-C[i].U)<0){//如果直线Y与三角形相交
Rd tmp=C[i].U-Y;//交线长度
if(dcmp(tmp)>0)Seg[++t]=Segment(C[i].x,C[i].x+tmp);//储存交线
}

判断小三角形是否被大三角形所包含:

inline int TIT(Triangle A,Triangle B){//判断三角形A是否在三角形B以内
return A.L>=B.L&&A.R<=B.R&&A.D>=B.D&&A.U<=B.U&&dcmp(A.R-(B.x+B.U-A.y))<=0;
}

完了?

...

\(\text{WA}\) 了!

为什么?

在用辛普森求平面图形面积时,如果对象是圆,那么一定不可能一次性满足精度要求(误差极大),但如果是三角形的话很可能一次计算就结束了递归

看下图:

对于第一次递归求解 \((l,r)\),用公式计算 \(now=Simpson(l,r),FL=Simpson(l,mid),FR=Simpson(mid,r)\) 时使用了上图中的 \(5\) 条横线,发现它们都没有经过左边的小三角形,而此时 \(now,FL,FR\) 都是算的大三角形的准确面积,所以递归会直接终止,最终只返回了大三角形的面积,小三角形被忽略。

为什么算 圆面积并 时没有出现这种问题呢?前面说了 计算对象为圆时不可能一次性满足精度要求,也就是说必定会递归扫描到各个位置,不会存在漏掉某一小块的情况。

解决方案(该思路来自 \(\text{Edgration}\) 巨佬 ):

记录所有的 \(y,y+m\) 并排序去重,对于所有相邻两端点所围住的范围单独处理。如下图,分别递归计算 \((Y_1,Y_2),(Y_2,Y_3),(Y_3,Y_4)\) 三块并求和。

精度!精度!!!

三角形 开 \(1e\!-\!9\),三角形覆盖问题 开 \(1e\!-\!10\) 。

调参调出了写模拟退火的感觉

【Code】

#pragma GCC optimize(3,"Ofast","inline")
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<map>
#define LD double
#define LL long long
#define Re register int
#define Rd register LD
#define Vector Point
using namespace std;
const int N=2003;
const LD eps=1e-9;
int n,m;map<LD,LD>vis;
inline int dcmp(Rd a){return a<-eps?-1:(a>eps?1:0);}
struct Point{
LD x,y;Point(LD X=0,LD Y=0){x=X,y=Y;}
inline void in(){scanf("%lf%lf",&x,&y);}
};
struct Segment{
LD L,R;Segment(LD l=0,LD r=0){L=l,R=r;}
inline bool operator<(Segment O)const{return L!=O.L?L<O.L:R<O.R;}
}Seg[N];
struct Triangle{
LD x,y,m,L,R,D,U;
inline void in(){scanf("%lf%lf%lf",&x,&y,&m),L=x,R=x+m,D=y,U=y+m;}
}C[N],C_[N];
inline bool cmp(Triangle A,Triangle B){return A.m<B.m;}//按直角边长排序
inline LD F(Rd Y){
if(vis[Y])return vis[Y];
Re t=0;Rd ans=0;
for(Re i=1;i<=n;++i)
if(dcmp(Y-C[i].D)>=0&&dcmp(Y-C[i].U)<0){//如果直线Y与三角形相交
Rd tmp=C[i].U-Y;//交线长度
if(dcmp(tmp)>0)Seg[++t]=Segment(C[i].x,C[i].x+tmp);//储存交线
}
if(!t)return 0.0;
sort(Seg+1,Seg+t+1);
for(Re i=1,j;i<=t;i=j+1){
Rd L=Seg[i].L,R=Seg[i].R;j=i;
while(j<t&&Seg[j+1].L<=R)++j,R=max(R,Seg[j].R);
ans+=R-L;
}
return vis[Y]=ans;
}
inline LD Simpson(Rd L,Rd R){return (R-L)*(F(L)+4.0*F((L+R)*0.5)+F(R))/6.0;}
inline LD sakura(Rd L,Rd R,Rd now){
Rd mid=(L+R)*0.5,FL=Simpson(L,mid),FR=Simpson(mid,R);
if(!dcmp(now-FL-FR))return now;
return sakura(L,mid,FL)+sakura(mid,R,FR);
}
inline int TIT(Triangle A,Triangle B){//判断三角形A是否在三角形B以内
return A.L>=B.L&&A.R<=B.R&&A.D>=B.D&&A.U<=B.U&&dcmp(A.R-(B.x+B.U-A.y))<=0;
}
LD ans,YY[N<<1];
int main(){
// freopen("456.txt","r",stdin);
scanf("%d",&m);Re t=0;
for(Re i=1;i<=m;++i)C_[i].in();
sort(C_+1,C_+m+1,cmp),C[++n]=C_[m];//按半径大小排序
for(Re i=m-1;i>=1;--i){
Re flag=1;
for(Re j=1;j<=n&&flag;++j)if(TIT(C_[i],C[j]))flag=0;
if(flag)C[++n]=C_[i];
}
for(Re i=1;i<=n;++i)YY[++t]=C[i].D,YY[++t]=C[i].U;
sort(YY+1,YY+t+1);
for(Re i=2;i<=t;++i)//若干个小块分别处理
if(dcmp(YY[i]-YY[i-1])>0){
Rd D=YY[i-1],U=YY[i]-2*eps;//这里必须要偏移边界,否则会死得非常难看
ans+=sakura(D,U,Simpson(D,U));
}
printf("%.1lf",ans);
}

【题解】三角形 [P1222] / 三角形覆盖问题 [HNOI2012] [P3219]的更多相关文章

  1. 利用CSS3中transparent实现三角形及三角形组合图

    ??如何绘制三角形及三角形的组合图案,以下是自己画的草图 源码如下 <!DOCTYPE html> <html lang="en"> <head> ...

  2. CSS3中三角形及三角形组合图实现

        几何之三角形及三角形的组合图案理论 三角形( triangle ['traɪæŋɡl])可以看成正方形对角线交叉形成的图形 若想得到编号①方向向下三角形,只需对编号②③④三角形让其透明tran ...

  3. 洛谷 题解 P1284 【三角形牧场】

    状态: dp[i][j]表示用i和j的木板能否搭成,不用去管第三块,因为知道了两块的长度与周长,那就可以表示出第三块:c-i-j 转移 有点类似于背包 if((j-l[i]>=0&&am ...

  4. Java 写三角形 空心三角形 菱形 空心菱形

    闲来无事,练习了一下Java基础中的循环语句.练习循环语句,当然少不了,用*打印出来三角形.空心三角形.菱形等这样的几何图形. 粗心大意,失误两次: 一.三角形 遇到一些小问题: 二.金字塔 由于三角 ...

  5. 题解 P1034 【矩形覆盖】

    题面 在平面上有n个点(n≤50),每个点用一对整数坐标表示.例如:当n=4时,4个点的坐标分另为:p1(1,1),p2(2,2),p3(3,6),P4(0,7),见图一. 这些点可以用k个矩形(1≤ ...

  6. HDU 1249 三角形(三角形分割平面)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1249 三角形 Time Limit: 2000/1000 MS (Java/Others)    Me ...

  7. css 三角形空心三角形的简单实现

    <style> #talkbubble { width: 120px; height: 80px; position: relative; -moz-border-radius: 10px ...

  8. [题解] LuoguP2764 最小路径覆盖问题

    传送门 好久没做网络流方面的题发现自己啥都不会了qwq 题意:给一张有向图,让你用最少的简单路径覆盖所有的点. 考虑这样一个东西,刚开始,我们有\(n\)条路径,每条路径就是单一的一个点,那么我们的目 ...

  9. 题解 洛谷P1990 覆盖墙壁

    DP康复训练题 原题:洛谷P1990 核心:递推/DP 题源应该是铺地砖,所以采用一摸一样的思路,只是有两种不同的方块 我们先用最最简单的方式尝试一下枚举当最后一行被填满的情况: 1.如果我们只用第一 ...

随机推荐

  1. cetos6.5 gcc4.8 安装

    1.准备源 #安装仓库 wget http://people.centos.org/tru/devtools-2/devtools-2.repo mv devtools-2.repo /etc/yum ...

  2. Serilog 源码解析——数据的保存(中)

    上一篇文章中揭露了日志数据的绑定逻辑,主要说明了日志数据绑定的结果信息,即EventProperty结构体和LogEventProperty类,以及日志数据与具名属性Token的绑定类Property ...

  3. linux中KVM桥接网卡br0

    在centos虚拟化当中需要增加一个桥接网卡,然后将虚拟化当中的机器的网卡桥接到桥接网卡,下面将描述设置方法: 查看现有网卡 [root@zb ~]# vim /etc/sysconfig/netwo ...

  4. CTDB与LVS搭建集群

    搭建一个采用lvs进行负载均衡的CTDB集群,整个集群的架构是采用如图所示 在上图所示的架构图中,后端采用的集群是我们的存储,集群存储的三个samba服务器的node在作为CTDB的节点的同时,也是运 ...

  5. [C/C++]详解结构体

    引子 设计程序时,最重要的步骤之一就是选择表示数据的方法.在许多情况下,简单变量甚至是数组还不够.为此,C提供了结构变量(structure variable)提高表示数据的能力,它能够创造新的形式. ...

  6. Redis订阅

    1.Redis订阅简介 进程间的一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息. 2.Redis订阅命令 3.Redis订阅的使用 先订阅后发布后才能收到消息, 1 可以一次性订 ...

  7. Kubernetes K8S之Taints污点与Tolerations容忍详解

    Kubernetes K8S之Taints污点与Tolerations容忍详解与示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-master C ...

  8. 应用程序-特定 权限设置并未向在应用程序容器不可用 SID (不可用)中运行的地址 LocalHost (使用 LRPC) 中的用户...的 COM 服务器应用程序的 本地 激活 权限。此安全权限可以使用组件服务管理工具进行修改。

    很久以前发现我们的业务服务器上出现一个System的系统严重错误,查找很久都没有找到解决办法,今日再次查看服务器发现报错更频繁,于是就搜集各种资料进行查找解决办法,终于找到了一个解决办法. 错误截图介 ...

  9. FL Studio通道窗口和步进音序器知识讲解

    FL Studio中通道窗口是以样本为概念的音乐制作基础.通道窗口包含了步进音序器并结合了各种丰富的功能,可以通过通道窗口打开各通道的设置窗口.钢琴卷轴等.步进音序器在节奏制作方便表现出很好的优势,它 ...

  10. 使用Sidechain EQ优化FLStudio的贝斯和底鼓

    混音的目标之一是平衡各个声音的音量.当两个声音占据相同的频率范围时,有时就比较难处理.这是贝司和底鼓之间经常会碰到的情况.很多时候我们会使用压缩(compression)来降低他们的音量.  然而,有 ...