雪色光晕(计算几何)
作者:互联网
题目链接https://ac.nowcoder.com/acm/contest/23479/D
今年的雪来得格外的早。雪把大地染成一片橙色。
小红正在雪地中奔跑。雪地可以看成是一个二维平面,小红的初始坐标是 (x0,y0),她每秒有个方向向量 (xi,yi),会沿着该方向直线奔跑1秒(例如,第一秒之后,小红的坐标就变成了 (x0+x1,y0+y1)(。小果站在坐标(x,y)处原地不动。小红想知道,在跑步过程中,自己和小果的最短距离是多少?
输入描述
第一行是一个正整数 n ,代表小红奔跑的总时间。 第二行是四个整数 x0、 y0、x 和 y ,用空格隔开。用来表示小红的初始坐标和小果的坐标。
接下来的n行,每行输入两个整数 xi 和 yi ,用来表示小红每秒的方向向量坐标。
数据范围:
1≤n≤200000
−10^9≤x,y,xi,yi≤10^9
输出描述
小红离小果最近的距离。如果你的答案和正确答案的相对误差不超过10^−7,则认为答案正确。
题解
首先如何判断最终能不能取到点到直线距离呢?很简单,把点 P 和线段两个端点 A和 B ,这三个点连接成一个三角形,判断该三角形的角 A 和角 B 是否是钝角即可。判断钝角可以直接用勾股定理:a^2+b^2<c^2,则角 C 为钝角。
剩下的点到直线距离即三角形的高,用2*S/AB即可,三角形面积可用海伦公式
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
const int N = 1e5 + 5;
struct point
{
double x, y;
}now, guo;
double dis(point a, point b)
{
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
double S(point A, point B, point C)
{ //三点三角形面积
double a = dis(B, C), b = dis(A, C), c = dis(A, B);
double p = (a + b + c) / 2;
return sqrt(p * (p - a) * (p - b) * (p - c));
}
bool judge(point A, point B, point C)
{//判断角ABC是钝角
double a = dis(B, C), b = dis(A, C), c = dis(A, B);
return b * b > a * a + c * c;
}
double f(point a, point b, point c)
{//c点到ab线段的最小距离
double d1 = dis(a, c), d2 = dis(b, c);
if(judge(c, a, b) || judge(c, b, a))
return min(d1, d2);
double s = S(a, b, c);
double d3 = 2 * s / dis(a, b);
return min(min(d1, d2), d3);
}
int main()
{
int n, k;
double xt, yt, x0, y0;
scanf("%d", &n);
scanf("%lf%lf%lf%lf", &x0, &y0, &xt, &yt);
double ans = 1e16;
now.x = x0, now.y = y0, guo.x = xt, guo.y = yt;
for(int i = 1; i <= n; i++)
{
double x1, y1;
scanf("%lf%lf", &x1, &y1);
point aim;
aim.x = x1 + now.x, aim.y = y1 + now.y;
ans = min(ans, f(now, aim, guo));
now = aim;
}
printf("%.8lf", ans);
return 0;
}
标签:point,double,光晕,雪色,几何,y0,x0,include,dis 来源: https://blog.csdn.net/qq_45540671/article/details/123029412