1. 程式人生 > >[CareerCup] 7.5 A Line Cut Two Squares in Half 平均分割兩個正方形的直線

[CareerCup] 7.5 A Line Cut Two Squares in Half 平均分割兩個正方形的直線

7.5 Given two squares on a two-dimensional plane, find a line that would cut these two squares in half. Assume that the top and the bottom sides of the square run parallel to the x-axis

這道題給了我們兩個正方形,讓我們求一條可以講這兩個正方形平均分為兩個部分的直線,前提是兩個正方形都和x軸平行。那麼我們首先要知道啥樣的直線才能將一個正方形平均分為兩部分呢,答案是任意一條過正方形中心的直線,那麼將兩個正方形平均分為兩部分就是連線兩個正方形中心的直線。這道題需要我們建立多個類,點,直線,和正方形,是一道考察面向物件程式設計的好題目。其中點類由兩個double型的變量表示,直線類由兩個點類表示,正方形類由左上頂點和右下頂點還有邊長表示。比較重要的兩個子函式extend和cut,其中extend是求從一箇中心連向另一箇中心,且交另一箇中心的外邊緣的點,至於是內邊緣還是外邊緣由第三個引數的正負所決定。cut函式是求連線兩個中心的直線分別和兩個正方形的外邊緣的交點,兩點確定一條直線即可。可能作為讀者的你會問,為啥這麼麻煩,直接將兩個中點一連不就是直線了,為啥要這麼麻煩,這麼裝B。沒錯,樓主就是要帶你裝B帶你飛,這解法是為了防止人家要求滿足題意的線段,那麼線段兩個端點正好在正方形的邊上,沒錯,就是這麼拉風,參見程式碼如下:

class Point {
public:
    double _x, _y;
    Point(double x, double y): _x(x), _y(y) {};
};

class Line {
public:
    Point _start, _end;
    Line(Point start, Point end): _start(start), _end(end) {};
};

/*
  (left, top)_________
            |         |
            |         | size
            |_________|
                      (right, down)  
*/ class Square { public: double _left, _top, _right, _down, _size; Square(double left, double top, double right, double down, double size): _left(left), _top(top), _right(right), _down(down), _size(size) {}; Point middle() { return Point((_left + _right) * 0.5, (_top + _down) * 0.5
); } // Return the point whrere the line connecting mid1 and mid2 intercepts the edge of square 1. Point extend(Point mid1, Point mid2, double size) { double xdir = mid1._x < mid2._x ? -1 : 1; double ydir = mid1._y < mid2._y ? -1 : 1; if (mid1._x == mid2._x) return Point(mid1._x, mid1._y + ydir * size * 0.5); double slope = (mid1._y - mid2._y) / (mid1._x - mid2._x); double x1 = 0, y1 = 0; if (fabs(slope) == 1) { x1 = mid1._x + xdir * size * 0.5; y1 = mid1._y + ydir * size * 0.5; } else if (fabs(slope) < 1) { x1 = mid1._x + xdir * size * 0.5; y1 = slope * (x1 - mid1._x) + mid1._y; } else { y1 = mid1._y + ydir * size * 0.5; x1 = (y1 - mid1._y) / slope + mid1._x; } return Point(x1, y1); } // Calculate the line that connecting two mids Line cut(Square other) { Point p1 = extend(middle(), other.middle(), _size); Point p2 = extend(middle(), other.middle(), -1 * _size); Point p3 = extend(other.middle(), middle(), other._size); Point p4 = extend(other.middle(), middle(), -1 * other._size); Point start = p1, end = p1; vector<Point> points = {p2, p3, p4}; for (int i = 0;i < points.size(); ++i) { if (points[i]._x < start._x || (points[i]._x == start._x && points[i]._y < start._y)) { start = points[i]; } else if (points[i]._x > end._x || (points[i]._x == end._x && points[i]._y > end._y)) { end = points[i]; } } return Line(start, end); } };