uva 11796 Dog Distance(计算几何, 基础)

一道练习几何很好的题。可以帮你复习中学的姿势。。相对运动什么的。。

精度要求不高是很和谐的地方,不用担心累计误差。。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <queue>
#include <stack>
#include <cassert>
#include <algorithm>
#include <cmath>
#include <limits>
#include <set>
#include <map>

using namespace std;

#define MIN(a, b) a < b ? a : b
#define MAX(a, b) a > b ? a : b
#define F(i, n) for (int i=0;i<(n);++i)
#define REP(i, s, t) for(int i=s;i<=t;++i)
#define IREP(i, s, t) for(int i=s;i>=t;--i)
#define REPOK(i, s, t, o) for(int i=s;i<=t && o;++i)
#define MEM0(addr, size) memset(addr, 0, size)
#define LBIT(x) x&-x

#define PI 3.1415926535897932384626433832795
#define HALF_PI 1.5707963267948966192313216916398

#define MAXN 300
#define MAXM 100
#define MOD 20071027

typedef long long LL;

const double maxdouble = numeric_limits<double>::max();
const double eps = 1e-10;
const int INF = 0x7FFFFFFF;

struct Point {
    double x, y;
    Point(){};
    Point(double x, double y):x(x),y(y){};
};
typedef Point Vector;

Vector operator - (Point A, Point B) {
    return Vector(A.x-B.x, A.y - B.y);
}
Vector operator + (Point A, Point B) {
    return Vector(A.x+B.x, A.y+B.y);
}
Vector operator * (Vector A, double p) {
    return Vector(A.x*p, A.y*p);
}
Vector operator / (Vector A, double p) {
    return Vector(A.x/p, A.y/p);
}
int dcmp(double x) {
    if (fabs(x) < eps)
        return 0;
    else
        return x < 0 ? -1 : 1;
}

bool operator == (const Point& a, const Point& b) {
    if (dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0)
        return true;
    return false;
}
bool operator < (const Point& a, const Point& b) {
    return a.x < b.x || (a.x == b.x && a.y < b.y);
}
double Dot(Vector A, Vector B) {
    return A.x*B.x + A.y*B.y;
}
double Cross(Vector A, Vector B) {
    return A.x*B.y-A.y*B.x;
}
double Length(Vector A) {
    return sqrt(Dot(A, A));
}
double Area2(Point A, Point B, Point C) {
    return Cross(B-A, C-A);
}
double Angle(Vector A, Vector B) {
    return acos(Dot(A, B) / Length(A) / Length(B));
}
Vector Rotate(Vector A, double rad) {
    return Vector(A.x*cos(rad)-A.y*sin(rad), A.x*sin(rad)+A.y*cos(rad));
}
// 单位法线 左转90度后归一化
Vector Normal(Vector A) {
    double L = Length(A);
    return Vector(-A.y/L, A.x/L);
}
Point GetLineIntersection(Point P, Vector v, Point Q, Vector w) {
    Vector u = P - Q;
    double t = Cross(w, u) / Cross(v, w);
    return P + v*t;
}
bool SeqmentProperIntersection(Point a1, Point a2, Point b1, Point b2) {
    double c1 = Cross(a2-a1, b2-a1), c2 = Cross(a2-a1, b1-a1),
           c3 = Cross(b2-b1, a2-b1), c4 = Cross(b2-b1, a1-b1);
    if (dcmp(c1)*dcmp(c2) < 0 && dcmp(c3)*dcmp(c4) < 0)
        return true;
    return false;
}
bool OnSegment(Point p, Point a1, Point a2) {
    return dcmp(Cross(a1-p, a2-p)) == 0 && dcmp(Dot(a1-p, a2-p)) < 0;
}
double DistanceToSegment(Point P, Point A, Point B) {
    if (A == B)
        return Length(P - A);
    Vector v1 = B - A, v2 = P - A, v3 = P - B;
    if (dcmp(Dot(v1, v2)) < 0) // 投影在A的外侧
        return Length(v2); // 投影在B的外侧
    else if (dcmp(Dot(v1, v3)) > 0)
        return Length(v3);
    else
        return fabs(Cross(v1, v2)) / Length(v1);
}
double cos_theorem(double edge1, double edge2, double edge3) {
    return acos((pow(edge1, 2.0) + pow(edge2, 2.0) - pow(edge3, 2.0)) / (2*edge1*edge2));
}

Point seq1[MAXN + 1];
Point seq2[MAXN + 1];

void update(double& _min, double& _max, Point P, Point A, Point B) {
    _min = min(_min, DistanceToSegment(P, A, B));
    _max = max(_max, Length(P-A));
    _max = max(_max, Length(P-B));
}

int main()
{
    freopen("input.in", "r", stdin);
    int N;

    scanf("%d", &N);
    F(ncases, N) {
        int A, B;
        int now1, now2;
        double len1, len2;
        Point p1, p2;
        scanf("%d%d",&A, &B);
        len1 = 0;
        len2 = 0;
        F(i, A) {
            scanf("%lf%lf",&seq1[i].x, &seq1[i].y);
            if (i > 0)
                len1 += Length(seq1[i]-seq1[i-1]);
        }
        F(i, B) {
            scanf("%lf%lf",&seq2[i].x, &seq2[i].y);
            if (i > 0)
                len2 += Length(seq2[i]-seq2[i-1]);
        }

        p1 = seq1[0], p2 = seq2[0];
        now1 = now2 = 0;
        double _min = Length(seq1[0]-seq2[0]);
        double _max = Length(seq1[0]-seq2[0]);
        while(now1 < A-1 && now2 < B - 1) {
            double r1 = Length(seq1[now1+1]-p1);
            double r2 = Length(seq2[now2+1]-p2);
            // 时间
            double t = min(r1/len1, r2/len2);
            // 速度向量
            //Vector v1 = (seq1[now1+1]-seq1[now1])/Length(seq1[now1+1]-seq1[now1])*len1*t;
            //Vector v2 = (seq2[now2+1]-seq2[now2])/Length(seq2[now2+1]-seq2[now2])*len2*t;
            Vector v1 = (seq1[now1+1]-p1) / r1 * len1 * t;
            Vector v2 = (seq2[now2+1]-p2) / r2 * len2 * t;
            update(_min, _max, p1, p2, p2 + v2-v1);
/*
            int diff = dcmp(r1 - r2);
            if (diff < 0) {
                p1 = seq1[++now1];
                p2 = p2 + v2*t;
            } else if (diff > 0) {
                p1 = p1 + v1*t;
                p2 = seq2[++now2];
            } else {
                p1 = seq1[++now1];
                p2 = seq2[++now2];
            }
*/
            p1 = p1 + v1;
            p2 = p2 + v2;
            if (p1 == seq1[now1+1])
                p1 = seq1[++now1];
                //++now1;
            if (p2 == seq2[now2+1])
                p2 = seq2[++now2];
                //++now2;
        }
        printf("Case %d: %.0f\n",ncases+1, _max - _min);
    }

    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值