zoukankan      html  css  js  c++  java
  • [CF1032D] Barcelonian Distance

    Description

    给出一个在二维平面直角坐标系第一象限内的,单位长度为 (1) 的无限大网格,每条直线都代表道路。又给你一条直线 (ax+by+c=0),也代表一条道路。
    现在给你两个格点 (A,B) 坐标 ((x1,y1))((x2,y2)),让你求该两点间最短的道路距离。

    Solution

    求矩形交点后再求距离

    (又把 fabs 写成 abs

    (以及关错了流同步被迫害

    #include <bits/stdc++.h>
    using namespace std;
    #define mp make_pair
    #define fi first
    #define se second
    #define pb push_back
    typedef double db;
    const db eps = 1e-6;
    const db pi = acos(-1);
    int sign(db k) {
    	if (k > eps) return 1; else if (k < -eps) return -1; return 0;
    }
    int cmp(db p1, db p2) { return sign(p1 - p2); }
    int inmid(db p1, db p2, db p3) { return sign(p1 - p3) * sign(p2 - p3) <= 0; }
    
    struct point {
    	db x, y;
    	point operator + (const point& p1) const { return (point) { p1.x + x, p1.y + y }; }
    	point operator - (const point& p1) const { return (point) { x - p1.x, y - p1.y }; }
    	point operator * (db p1) const { return (point) { x* p1, y* p1 }; }
    	point operator / (db p1) const { return (point) { x / p1, y / p1 }; }
    	int operator == (const point& p1) const { return cmp(x, p1.x) == 0 && cmp(y, p1.y) == 0; }
    	// 逆时针旋转
    	point turn(db p1) { return (point) { x* cos(p1) - y * sin(p1), x* sin(p1) + y * cos(p1) }; }
    	point turn90() { return (point) { -y, x }; }
    	bool operator < (const point p1) const {
    		int a = cmp(x, p1.x);
    		if (a == -1) return 1; else if (a == 1) return 0; else return cmp(y, p1.y) == -1;
    	}
    	db fabs() { return sqrt(x * x + y * y); }
    	db fabs2() { return x * x + y * y; }
    	db dis(point p1) { return ((*this) - p1).fabs(); }
    	point unit() { db w = fabs(); return (point) { x / w, y / w }; }
    	void scan() { double p1, p2; scanf("%lf%lf", &p1, &p2); x = p1; y = p2; }
    	void print() { printf("%.11lf %.11lf
    ", x, y); }
    	db getw() { return atan2(y, x); }
    	point getdel() { if (sign(x) == -1 || (sign(x) == 0 && sign(y) == -1)) return (*this) * (-1); else return (*this); }
    	int getP() const { return sign(y) == 1 || (sign(y) == 0 && sign(x) == -1); }
    };
    int inmid(point p1, point p2, point p3) { return inmid(p1.x, p2.x, p3.x) && inmid(p1.y, p2.y, p3.y); }
    db cross(point p1, point p2) { return p1.x * p2.y - p1.y * p2.x; }
    db dot(point p1, point p2) { return p1.x * p2.x + p1.y * p2.y; }
    db rad(point p1, point p2) { return atan2(cross(p1, p2), dot(p1, p2)); }
    // -pi -> pi
    int compareangle(point p1, point p2) {
    	return p1.getP() < p2.getP() || (p1.getP() == p2.getP() && sign(cross(p1, p2)) > 0);
    }
    point proj(point p1, point p2, point q) { // q 到直线 p1,p2 的投影
    	point k = p2 - p1; return p1 + k * (dot(q - p1, k) / k.fabs2());
    }
    point reflect(point p1, point p2, point q) { return proj(p1, p2, q) * 2 - q; }
    int clockwise(point p1, point p2, point p3) {// p1 p2 p3 逆时针 1 顺时针 -1 否则 0
    	return sign(cross(p2 - p1, p3 - p1));
    }
    
    
    int checkLL(point p1, point p2, point p3, point p4) {// 求直线 (L) 线段 (S)p1,p2 和 p3,p4 的交点
    	return cmp(cross(p3 - p1, p4 - p1), cross(p3 - p2, p4 - p2)) != 0;
    }
    point getLL(point p1, point p2, point p3, point p4) {
    	db w1 = cross(p1 - p3, p4 - p3), w2 = cross(p4 - p3, p2 - p3); return (p1 * w2 + p2 * w1) / (w1 + w2);
    }
    int intersect(db l1, db r1, db l2, db r2) {
    	if (l1 > r1) swap(l1, r1); if (l2 > r2) swap(l2, r2); return cmp(r1, l2) != -1 && cmp(r2, l1) != -1;
    }
    int checkSS(point p1, point p2, point p3, point p4) {
    	return intersect(p1.x, p2.x, p3.x, p4.x) && intersect(p1.y, p2.y, p3.y, p4.y) &&
    		sign(cross(p3 - p1, p4 - p1)) * sign(cross(p3 - p2, p4 - p2)) <= 0 &&
    		sign(cross(p1 - p3, p2 - p3)) * sign(cross(p1 - p4, p2 - p4)) <= 0;
    }
    db disSP(point p1, point p2, point q) {
    	point p3 = proj(p1, p2, q);
    	if (inmid(p1, p2, p3)) return q.dis(p3); else return min(q.dis(p1), q.dis(p2));
    }
    db disSS(point p1, point p2, point p3, point p4) {
    	if (checkSS(p1, p2, p3, p4)) return 0;
    	else return min(min(disSP(p1, p2, p3), disSP(p1, p2, p4)), min(disSP(p3, p4, p1), disSP(p3, p4, p2)));
    }
    int onS(point p1, point p2, point q) { return inmid(p1, p2, q) && sign(cross(p1 - q, p2 - p1)) == 0; }
    struct line {
    	// p[0]->p[1]
    	point p[2];
    	line(point p1, point p2) { p[0] = p1; p[1] = p2; }
    	point& operator [] (int k) { return p[k]; }
    	int include(point k) { return sign(cross(p[1] - p[0], k - p[0])) > 0; }
    	point dir() { return p[1] - p[0]; }
    	line push() { // 向外 ( 左手边 ) 平移 eps
    		const db eps = 1e-6;
    		point delta = (p[1] - p[0]).turn90().unit() * eps;
    		return { p[0] - delta,p[1] - delta };
    	}
    };
    point getLL(line p1, line p2) { return getLL(p1[0], p1[1], p2[0], p2[1]); }
    int parallel(line p1, line p2) { return sign(cross(p1.dir(), p2.dir())) == 0; }
    int sameDir(line p1, line p2) { return parallel(p1, p2) && sign(dot(p1.dir(), p2.dir())) == 1; }
    int operator < (line p1, line p2) {
    	if (sameDir(p1, p2)) return p2.include(p1[0]);
    	return compareangle(p1.dir(), p2.dir());
    }
    int checkpos(line p1, line p2, line p3) { return p3.include(getLL(p1, p2)); }
    
    double man(point p1,point p2) {
        return fabs(p1.x-p2.x)+fabs(p2.y-p1.y);
    }
    
    signed main() {
        double a,b,c;
        point p1={0,0},p2={0,0},q1={0,0},q2={0,0};
        cin>>a>>b>>c;
        p1.scan();
        p2.scan();
        if(fabs(a)<1e-6) {
            q1={-2e9,-c/b};
            q2={2e9,-c/b};
        }
        else {
            q1={-2e9,-(-2e9*a+c)/b};
            q2={2e9,-(2e9*a+c)/b};
        }
        point p3={p1.x,p2.y};
        point p4={p2.x,p1.y};
        double ans=man(p1,p2);
        point i1,i2;
        vector<point> vec;
        if(checkSS(p1,p3,q1,q2)) vec.push_back(getLL(p1,p3,q1,q2));
        if(checkSS(p1,p4,q1,q2)) vec.push_back(getLL(p1,p4,q1,q2));
        if(checkSS(p2,p3,q1,q2)) vec.push_back(getLL(p2,p3,q1,q2));
        if(checkSS(p2,p4,q1,q2)) vec.push_back(getLL(p2,p4,q1,q2));
        if(vec.size()>1) {
            i1=vec[0],i2=vec[1];
            if(i1==i2 && vec.size()>2) i2=vec[2];
            if(i1==i2 && vec.size()>3) i2=vec[3];
            ans=min(ans,i1.dis(i2)+man(p1,i1)+man(p2,i2));
            ans=min(ans,i1.dis(i2)+man(p1,i2)+man(p2,i1));
        }
        printf("%.10lf",ans);
    }
    
    
  • 相关阅读:
    快速切题 sgu102.Coprimes 欧拉函数 模板程度 难度:0
    快速切题 sgu104. Little shop of flowers DP 难度:0
    poj 1163 The Triangle 搜索 难度:0
    sgu101 欧拉路径 难度:1
    快速切题 poj3414 Pots
    xml学习
    linux
    常用排序算法
    C++面试题目
    软件工程的一些问题
  • 原文地址:https://www.cnblogs.com/mollnn/p/12845675.html
Copyright © 2011-2022 走看看