蓝桥杯 还有多远才能见到你
题意
如果我们之间的距离是一千步,我会向你走出九百九十九步,只要你向我的方向迈出最后的一步。后来,我朝你的方向走了一千步,我却不知道你在哪里。
(写题写出了网抑云...)
给定\(n,m\)个点 , 分别代表两个折线段 , 求其中折线段相距最近的距离
思路
第一次做计算几何的题
点到线段的距离
利用点积可以判断垂足是否在线段内 , 否则判断到两个端点距离的最小值即可
线段到线段的最短距离
相交为0
否则 , 最短距离即四个点到另一条线段的距离的最小值
考虑一些计算几何的基础知识
0. sg : 通过与eps比较来判断正负零
- 读取double , 不要用read
- 减号的重载
struct Point
{
double x,y;
operaotr-(const Point& other){
return {x-other.x,y-other.y};
}
}
- 距离 , 点积 , 叉积
double distance(Point x,Point y)
{ }//略
double Dot(Point a,Point b)
{
return a.x * b.x + a.y * b.y;//用于判断夹角
}
double Cross(Point a,Point b)
{
return a.x * b.y - a.y * b.x;//判断是否相交 , 或者用于计算垂线长度
}
- 判断相交
bool xj(P a,P b,P c,P d)
{
double c1 = Cross(b-a,c-a),c2=Cross(b-a,d-a);
double d1 = Cross(a-c,d-c),d2=Cross(b-c,d-c);
return sg(c1) * sg(c2) < 0 && sg(d1) * sg(c2) < 0;
}
- 求点到线长度
double getlen(P p,P a,P b)
{
return fabs(Cross(p-a,a-b))/Distance(a,b);
}
代码
#include<bits/stdc++.h>
using namespace std;
const double eps = 1e-8;
struct Point {
double x,y;
Point operator-(const Point &a) {
return {x-a.x,y-a.y};
}
};
double Distance(Point a,Point b) {
return sqrt((a.x-b.x) * (a.x -b.x) + (a.y - b.y) * (a.y - b.y));
}
double Dot(Point a,Point b) {
return a.x * b.x + a.y * b.y;
}
double Cross(Point a,Point b) {
return a.x * b.y - a.y * b.x;
}
double sg(double x) {
if (x > eps) return 1;
if (x<-eps) return -1;
return 0;
}
double xj(Point a,Point b,Point c,Point d) {
double c1 = Cross(b-a,c-a),c2 = Cross(b-a,d-a);
double d1 = Cross(d-c,a-c),d2 = Cross(d-c,b-c);
return sg(c1) * sg(c2) < 0 && sg(d1) * sg(d2) < 0;
}
double getlen(Point p,Point a,Point b) {
return fabs(Cross(p-a,a-b))/Distance(a,b);
}
double f(Point p,Point a,Point b) {
if (Dot(p-a,b-a) < 0 || Dot(p-b,a-b)<0) {
return min(Distance(p,a),Distance(p,b));
}
return getlen(p,a,b);
}
int main() {
int n,m;
cin>>n>>m;
vector<Point> a(n),b(m);
for (int i = 0; i< n; i++) {
cin>>a[i].x>>a[i].y;
}
for (int i = 0; i< m; i++) {
cin>>b[i].x>>b[i].y;
}
double ans = 2e18+7;
for (int i = 1; i< n; i++) {
for (int j = 1; j< m; j++) {
if (xj(a[i],a[i-1],b[j],b[j-1])) {
ans = 0;
break;
}
ans = min({ans,
f(a[i],b[j],b[j-1]),
f(a[i-1],b[j],b[j-1]),
f(b[j],a[i],a[i-1]),
f(b[j-1],a[i],a[i-1])
});
}
}
cout<<fixed<<setprecision(3)<<ans<<"\n";
return 0;
}

浙公网安备 33010602011771号