其他分享
首页 > 其他分享> > CF1642A 题解

CF1642A 题解

作者:互联网

题目传送门

题目大意

在平面直角坐标系上,有一个三角形,给出三角形的三个顶点的坐标 \((x_i,y_i)\),其中 \(x_i,y_i\) 均为整数且 \(0\le x_i,y_i\le 10^9\)。
如果存在一条线段,这条线段的端点在 \(x\) 轴上,另一个端点在三角形上,并且这条线段不穿过三角形内部,那么就称三角形上的这个点是安全的。
现在要求 不是 安全的点组成的线段(或者是折线)的长度。

题目解析

首先,不难证明,如果一条边的斜率不等于 \(0\),那么这条线段上的点肯定是安全的。
证明如下:
如果第三个点在这条线段上方,那么直接做一条到 \(x\) 轴的垂线即可。否则就过这一点做一条斜率的绝对值比原来的线段更小并且同号的线段即可。

也就是说我们只需要考虑斜率等于 \(0\) 的线段。
这时需要分类讨论。
如果三角形的另一个点在这条线段上方,我们只需要作一条到 \(x\) 轴的垂线就可以的。
如果三角形的另一个点在这条线段下方,那么这条线段上的点(除了线段端点)不是安全的点。

因此枚举三条边判断即可。

代码(主要部分):

struct JTZ{
	ll x,y;
}a[39];
db dis(JTZ x,JTZ y){ return sqrt((x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y)); }
void work(){
	int i; db ans=0;
	for(i=1;i<=3;i++) a[i].x=read(),a[i].y=read();
	if(a[1].y==a[2].y&&a[3].y<a[1].y) ans+=dis(a[1],a[2]);
	if(a[1].y==a[3].y&&a[2].y<a[1].y) ans+=dis(a[1],a[3]);
	if(a[2].y==a[3].y&&a[1].y<a[2].y) ans+=dis(a[2],a[3]);
	printf("%lf\n",ans);
}

标签:一条,JTZ,题解,CF1642A,斜率,端点,三角形,线段
来源: https://www.cnblogs.com/jiangtaizhe001/p/15932359.html