uvaoj 11796 - Dog Distance

题解:
1.发现两条线的距离变化有时候是呈一次函数,有时候呈二次变化,所以对于处理二次变化的时候比较麻烦
2.两个点的变化,想象成一个点不动,另一个点是两个点的运动叠加
总结:
1.没有想出来这道题目,今天有些感冒,感觉头脑不利索,想起题目来总是不转,以后碰到这种情况,应该做些别的不太用动脑子也可以做的事情,提高工作效率
2.对于这道题,总结一下:减少变量,简化题目的思想,就像一道题目(例如汉诺塔那道题),我不知道怎么做,先举几个小例子来帮助思考。
3.首先简化成:一个静点和一个动点的距离变化,通过考虑这个问题,也许可能能够自己思考出将两个点的移动合并成一个静点,一个动点的这步。
4.还有一点,对于变量名,尤其是在容易混淆的地方,尽量起的差别大一些,利于发现错误

#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<set>
struct Point {
  double x, y;
  Point(double x=0, double y=0):x(x),y(y) { }
};
const double eps = 1e-8;
const double PI = acos(-1.0);
int dcmp(double x) {
  if(fabs(x) < eps) return 0; else return x < 0 ? -1 : 1;
}
typedef Point Vector;

Vector operator + (const Vector& A, const Vector& B) { return Vector(A.x+B.x, A.y+B.y); }
Vector operator - (const Point& A, const Point& B) { return Vector(A.x-B.x, A.y-B.y); }
Vector operator * (const Vector& A, double p) { return Vector(A.x*p, A.y*p); }
Vector operator / (const Vector& A, double p) { return Vector(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);
}
bool operator == (const Point& a, const Point &b) {
  return dcmp(a.x-b.x) == 0 && dcmp(a.y-b.y) == 0;
}
bool operator != (const Point& a, const Point &b) {
  return !(a == b);
}
double Dot(const Vector& A, const Vector& B) { return A.x*B.x + A.y*B.y; }
double Length(const Vector& A) { return sqrt(Dot(A, A)); }
double Angle(const Vector& A, const Vector& B) { return acos(Dot(A, B) / Length(A) / Length(B)); }
double Cross(const Vector& A, const Vector& B) { return A.x*B.y - A.y*B.x; }
Point GetLineIntersection(const Point& P, const Point& v, const Point& Q, const Point& w) {
  Vector u = P-Q;
  double t = Cross(w, u) / Cross(v, w);
  return P+v*t;
}
Vector Rotate(const Vector& A, double rad) {
  return Vector(A.x*cos(rad)-A.y*sin(rad), A.x*sin(rad)+A.y*cos(rad));
}
bool SegmentProperIntersection(const Point& a1, const Point& a2, const Point& b1, const Point& b2) {
  double c1 = Cross(a2-a1,b1-a1), c2 = Cross(a2-a1,b2-a1),
  c3 = Cross(b2-b1,a1-b1), c4=Cross(b2-b1,a2-b1);
  return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0;
}
bool OnSegment(const Point& p, const Point& a1, const Point& a2) {
  return dcmp(Cross(a1-p, a2-p)) == 0 && dcmp(Dot(a1-p, a2-p)) < 0;
}
bool _OnSegment(const Point& p, const Point& a1, const Point& a2) {
  return dcmp(Cross(a1-p, a2-p)) == 0 && dcmp(Dot(a1-p, a2-p)) < 0
         && p != a1 && p != a2;
}
double DistanceToSegment(const Point& P, const Point& A, const 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);
}
Point read_point(){
  double x, y;
  scanf("%lf%lf", &x, &y);
  return Point(x,y);
}
#define MAXN 60
using namespace std;
Point a[MAXN],b[MAXN];
int main()
{
    int _,n1,n2;
    cin >> _;
    for(int kcas = 1;kcas <= _;kcas++)
    {
        cin >> n1 >> n2;
        for(int i = 0;i < n1;i++)a[i] = read_point();
        for(int i = 0;i < n2;i++)b[i] = read_point();
        double len1 = 0,len2 = 0;
        for(int i = 1;i < n1;i++)len1 += Length(a[i] - a[i - 1]);
        for(int i = 1;i < n2;i++)len2 += Length(b[i] - b[i - 1]);
        Point u1 = a[0],u2 = b[0];
        int i = 1,j = 1;
        double maxn = -1e9,minn = 1e9;
        while(i < n1 && j < n2)
        {
            double la = Length(a[i] - u1);
            double lb = Length(b[j] - u2);
            double p = min(la / len1,lb / len2);
            Vector d1 = (a[i] - u1) / la * p * len1;
            Vector d2 = (b[j] - u2) / lb * p * len2;
            maxn = max(maxn,Length(u2 - u1));
            maxn = max(maxn,Length((u2 + d2 - d1) - u1));
            minn = min(minn,DistanceToSegment(u1,u2,u2 + d2 - d1));
            u1 = u1 + d1;
            u2 = u2 + d2;
            if(u1 == a[i])i++;
            if(u2 == b[j])j++;
        }
        printf("Case %d: %.0lf\n",kcas,maxn - minn);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值