uva 11796

题意:两仅仅狗分别沿一条折线跑,速度未知,但同一时候出发同一时候到达。分别给出两条折线的各点坐标,问两仅仅狗在跑的过程中的最远距离和近期距离差。
题解:假设两仅仅狗跑的都是线段,问题会更easy解决,能够把当中一点当做精巧,还有一个做相对运动,就能够求出这个过程的最远近期距离,然后假设是走折线,两个点先到拐点的之前的时间段就是前面说的简化过程,也就是把整个过程划分为好多个简化过程阶段。

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
using namespace std;
const int N = 60;
struct Point {
    double x, y;
    Point(double x = 0, double y = 0): x(x), y(y) {}
}A[N], B[N];
int n, m;
double maxx, minn;

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);
}
//计算点积的正负  负值夹角为钝角
int dcmp(double x) {
    if (fabs(x) < 1e-9)
        return 0;
    return x < 0 ?

-1 : 1; } bool operator < (const Point& a, const Point& b) { return a.x < b.x || (a.x == b.x && a.y < b.y); } 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; } //计算叉积,也就是数量积 double Cross(Point A, Point B) { return A.x * B.y - A.y * B.x; } //计算向量长度 double Length(Point A) { return sqrt(Dot(A, A)); } //向量A旋转rad弧度,rad负值为顺时针旋转 Point Rotate(Point A, double rad) { return Point(A.x * cos(rad) - A.y * sin(rad), A.x * sin(rad) + A.y * cos(rad)); } //得到两直线交点 Point GetLineIntersection(Point P, Point v, Point Q, Point w) { Point u = P - Q; double t = Cross(w, u) / Cross(v, w); return P + v * t; } //点p到线段AB的距离 double DistanceToSegment(Point p, Point A, Point B) { if (A == B) return Length(p - A); Point AB = B - A, AP = p - A, BP = p - B; if (dcmp(Dot(AB, AP)) < 0) return Length(AP); else if (dcmp(Dot(AB, BP)) > 0) return Length(BP); else return fabs(Cross(AB, AP)) / Length(AB); } //推断两个线段是否有交点(不包含端点) bool SegmentProperIntersection(Point a1, Point a2, Point b1, Point b2) { double c1 = Cross(a2 - a1, b1 - a1); double c2 = Cross(a2 - a1, b2 - a1); double c3 = Cross(b2 - b1, a1 - b1); double c4 = Cross(b2 - b1, a2 - b1); return dcmp(c1) * dcmp(c2) < 0 && dcmp(c3) * dcmp(c4) < 0; } //推断点p是否在线段a1--a2上(不包含端点) bool OnSegment(Point p, Point a1, Point a2) { return dcmp(Cross(a1 - p, a2 - p)) == 0 && dcmp(Dot(a1 - p, a2 - p)) < 0; } void update(Point P, Point A, Point B) { minn = min(minn, DistanceToSegment(P, A, B)); maxx = max(maxx, Length(P - A)); maxx = max(maxx, Length(P - B)); } int main() { int t, cas = 1; scanf("%d", &t); while (t--) { scanf("%d%d", &n, &m); double sum1 = 0, sum2 = 0; for (int i = 0; i < n; i++) { scanf("%lf%lf", &A[i].x, &A[i].y); if (i != 0) sum1 += Length(A[i] - A[i - 1]); } for (int i = 0; i < m; i++) { scanf("%lf%lf", &B[i].x, &B[i].y); if (i != 0) sum2 += Length(B[i] - B[i - 1]); } int cur1 = 0, cur2 = 0; Point pos1 = A[cur1], pos2 = B[cur2]; maxx = -1e9; minn = 1e9; while (cur1 < n - 1 && cur2 < m - 1) { double len1 = Length(A[cur1 + 1] - pos1); double len2 = Length(B[cur2 + 1] - pos2); double T = min(len1 / sum1, len2 / sum2); Point v1 = (A[cur1 + 1] - pos1) / len1 * T * sum1; //甲的位移 Point v2 = (B[cur2 + 1] - pos2) / len2 * T * sum2; //乙的位移 update(pos1, pos2, pos2 + v2 - v1);//相对位移 pos1 = pos1 + v1; pos2 = pos2 + v2; if (pos1 == A[cur1 + 1]) cur1++; if (pos2 == B[cur2 + 1]) cur2++; } printf("Case %d: %.0lf\n", cas++, maxx - minn); } return 0; }

posted @ 2017-08-01 08:07  jzdwajue  阅读(125)  评论(0编辑  收藏  举报