玲珑杯-射击气球-点到线段的距离

玲珑杯-射击气球-点到线段的距离

求点到线段的距离

由于网页显示吃tab键,缩进无法正常显示

对于空间V-xyz三维几何中点到水平线段的距离,可以投影到xy平面(欧式几何)上。distance = √(∆h ^2 + d ^2);

其中d为投影xy平面上的点到线段的距离。

线段端点a(x1, y1), b(x2, y2),任一点vxt, yt)。

若两端点a,b是否共点

d = 两点间距离

否则

若两端点和任意点v共线(用点积结果判断)

若 v 在线段ab上

d = 0;

否则 d = min(|va|, |vb|);

否则 

若三点组成钝角三角形(用余弦定理判断)

d = min(|va|, |vb|);

否则 d = 三角形abv的以ab为底的高(用点乘求得)

今天玲珑杯的A题,题不难,但过的不多,用了一些高中数学知识,大概这就是为啥高中生虐了大学生的部分原因吧。

#include <iostream>
#include <cstdio>
#include <queue>
#include <stack>
#include <string>
#include <cstring>
#include <map>
#include <set> 
#include <algorithm>
#include <cstdlib>
#include <cmath> 
using namespace std;
const int maxn = 1e4 + 7;

int main()
{
	ios::sync_with_stdio(false);
	int t;
	cin >> t;
	while(t--) {
		int x1, y1, H, x2, y2;
		cin >> H >> x1 >> y1 >> x2 >> y2;
		int x0, y0, h0, x, y, h;
		cin >> x0 >> y0 >> h0 >> x >> y >> h;
		int n;
		double line = sqrt(pow(x1 - x2, 2.0) + pow(y1 - y2, 2.0));
		cin >> n;
		while(n--) {
			int t;
			cin >> t;
			int xt = x0 + t* x;
			int yt = y0 + t * y;
			int ht = h0 + t * h;
			double d;
			if (x1 == x2 && y1 == y2) { //重合 
				d = sqrt(pow(xt - x1, 2.0) + pow(yt - y1, 2.0));
			} 
			else {
				if ((x1 - xt) * (y2 - yt) == (x2 - xt) * (y1 - yt)) { //共线 
					if(xt >= min(x1, x2) && yt <= max(y1, y2)) {
						d =  0.0;
					} 
					else {
						d = min(sqrt(pow(x1 - xt, 2.0) + pow(y1 - yt, 2.0)),
							 sqrt(pow(x2 - xt, 2.0) + pow(y2 - yt, 2.0)));
					}
				}
				else {
					if (line * line + pow(xt - x1, 2.0) + pow(yt - y1, 2.0) < pow(xt - x2, 2.0) + pow(yt - y2, 2.0) ||
						line * line + pow(xt - x2, 2.0) + pow(yt - y2, 2.0) < pow(xt - x1, 2.0) + pow(yt - y1, 2.0))
							d = min(sqrt(pow(x1 - xt, 2.0) + pow(y1 - yt, 2.0)),
							 sqrt(pow(x2 - xt, 2.0) + pow(y2 - yt, 2.0)));
					else d = fabs((x1 - xt) * (y2 - yt) - (x2 - xt) * (y1 - yt)) / line; 
				}
			}
			double ans = sqrt(pow(ht - H, 2.0) + d * d);
			printf("%.2lf\n", ans);
		}
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值