zoukankan      html  css  js  c++  java
  • UVA 11796Dog Distance[平面几何]

    刘汝佳白书上的题,有一个很好的技巧是把两个处于惯性参考系的物体中的一个看做静止,另一个做相对运动,把两个匀速运动的物体间的距离换成了静止的点到线段的距离。很好的题

    计算几何的题代码很多,注意细心。

    #include "bits/stdc++.h"
    using namespace std;
    const int maxn = 100;
    const double eps=1e-8;
    struct Point {
        double x, y;
        Point(double x = 0, double y = 0):x(x), y(y) {}
    };
    typedef Point Vector;
    Point operator + (Point A, Point B) {
        return Point(A.x+B.x, A.y+B.y);
    }
    Point operator - (Point A, Point B) {
        return Point(A.x-B.x, A.y-B.y);
    }
    Point operator * (Point A, double p) {
        return Point(A.x*p, A.y*p);
    }
    Point operator / (Point A, double p) {
        return Point(A.x/p, A.y/p);
    }
    bool operator < (const Point& a, const Point& b) {
        return a.x<b.x || (a.x==b.x && a.y<b.y);
    }
    int dcmp(double x) {
        if (fabs(x)<eps) return 0;return x<0?-1:1;
    }
    bool operator == (const Point& a, const Point &b) {
        return dcmp(a.x-b.x) == 0 && dcmp(a.y-b.y)==0;
    }
    double Dot(Point A, Point B) {
        return A.x*B.x+A.y*B.y;
    }
    //带方向的叉积,cross(x,y)=-cross(y,x)
    double Cross(Point A, Point B) {
        return A.x*B.y - A.y*B.x;
    }
    double Length(Point A) {return sqrt(Dot(A,A));}
    //向量之间的夹角
    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)) return Length(v2);
        else if(dcmp(Dot(v1,v3))>0) return Length(v3);
        else return fabs(Cross(v1,v2))/Length(v1);
    }
    void GetPoint(Point& P) {
        scanf("%lf%lf", &P.x, &P.y);
    }
    Point a[maxn], b[maxn];
    int main(int argc, char const *argv[])
    {
        int T;
        int Kcase = 0;
        scanf("%d", &T);
        while (T--) {
            int A, B;
            double lena = 0;
            double lenb = 0;
            scanf("%d%d", &A, &B);
            double minn = 0x3f3f3f3f, maxx = 0;
            for (int i = 0; i < A; i++) GetPoint(a[i]);
            for (int i = 0; i < B; i++) GetPoint(b[i]);
            int cnta = 0, cntb = 0;
            for (int i = 1; i < A; i++) lena += Length(a[i]-a[i-1]);
            for (int i = 1; i < B; i++) lenb += Length(b[i]-b[i-1]);
            double Va = lena, Vb = lenb;
            Point Pa = a[0], Pb = b[0];
            while (cnta < A-1 && cntb < B-1) {
                double La = Length(a[cnta+1]-Pa);
                double Lb = Length(b[cntb+1]-Pb);
                double time = min(La/Va, Lb/Vb);
                Vector Da = (a[cnta+1]-Pa)/La*time*Va;
                Vector Db = (b[cntb+1]-Pb)/Lb*time*Vb; 
                minn = min(minn, DistanceToSegment(Pa, Pb, Pb+Db-Da));
                maxx = max(maxx, Length(Pa-Pb));
                maxx = max(maxx, Length(Pa-Pb-Db+Da));
                Pa = Pa + Da; Pb = Pb + Db;
                if (Pa == a[cnta+1]) cnta++;
                if (Pb == b[cntb+1]) cntb++;
            }
            printf("Case %d: %.0lf
    ", ++Kcase, maxx-minn);
        }
        return 0;
    }
  • 相关阅读:
    IOS开发——01_第一个OC程序
    01_iOS开发需要准备什么?
    正则表达式随笔
    .net4.6版本前设置window子窗口位置主窗口闪烁
    [CF1486D] Max Median
    [CF1487D] Pythagorean Triples
    [CF1487E] Cheap Dinner
    [CF1490E] Accidental Victory
    [CF1490F] Equalize the Array
    [CF1490G] Old Floppy Drive
  • 原文地址:https://www.cnblogs.com/cniwoq/p/7287178.html
Copyright © 2011-2022 走看看