[CareerCup] 7.5 A Line Cut Two Squares in Half 平均分割两个正方形的直线


http://www.cnblogs.com/grandyang/p/4774754.html
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);
    }
};
https://github.com/shyal/cracking-the-coding-interview/blob/master/interviewQuestions.txt
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

public class Square {
public Point middle() {
        return new Point((this.left +this.right)/ 2.0, (this.top+ this.bottom)/ 2.0);
}

/* Return the point where the line segment connecting midl and mid2 intercepts
 * the edge of square 1. That is, draw a line from mid2 to midl, and continue it
 * out until the edge of the square. */
public Point extend(Point midl, Point mid2, double s ize) {
        /* Find what direction the line mid2 -> midl goes. */
        double xdir = midl.x < mid2.x ? -1 : 1;
        double ydir = midl.y < mid2.y ? -1 : 1;

        /* If midl and mid2 have the s ame x value, then the slope calculation will
         * throw a divide by 0 exception. So, we compute this specially. */
        if (midl.x == mid2.x) {
                return new Point(midl.x, midl.y + ydir * size/ 2.0);
        }

        double slope = (midl.y - mid2.y) / (midl.x - mid2.x);
        double xl = 0;
        double yl = 0;

        /* Calculate slope using the equation (yl - y2) / (xl - x2).
         * Note: if the slope is "steep" (>1) then the end of the line segment will
         * hit size/ 2 units away from the middle on the y axis. If the slope is
         * "shallow" ( <1) the end of the line segment will hit size / 2 units away
         * from the middle on the x axis. */
        if (Math.abs(slope) == 1) {
                xl = midl.x + xdir * size/ 2.0;
                yl = midl.y + ydir * size/ 2.0;
        } else if (Math.abs(slope) < 1) {// shallow slope
                xl = midl.x + xdir * size/ 2.0;
                yl = slope * (xl - midl.x) + midl.y;
        } else {// steep slope
                yl = midl.y + ydir * size/ 2.0;
                xl = (yl - midl.y) /slope + midl.x;
        }
        return new Point(xl, yl);
}

public Line cut(Square other) {
/* Calculate where a line between each middle would collide with the edges of
 * the squares */
        Point pl = extend(this.middle(), other.middle(), this.size);
        Point p2 = extend(this.middle(), other.middle(), -1 * this.size);
        Point p3 = extend(other.middle(), this.middle(), other.size);
        Point p4 = extend(other.middle(), this.middle(), -1 * other.size);

/* Of above points, find start and end of lines. Start is farthest left (with
 * top most as a tie breaker) and end is farthest right (with bottom most as
 * a tie breaker. */
        Point start = pl;
        Point end= pl;
        Point[] points = {p2, p3, p4};
        for (int i= 0; i < points.length; 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 new Line(start, end);
}
}

Labels

LeetCode (1432) GeeksforGeeks (1122) LeetCode - Review (1067) Review (882) Algorithm (668) to-do (609) Classic Algorithm (270) Google Interview (237) Classic Interview (222) Dynamic Programming (220) DP (186) Bit Algorithms (145) POJ (141) Math (137) Tree (132) LeetCode - Phone (129) EPI (122) Cracking Coding Interview (119) DFS (115) Difficult Algorithm (115) Lintcode (115) Different Solutions (110) Smart Algorithm (104) Binary Search (96) BFS (91) HackerRank (90) Binary Tree (86) Hard (79) Two Pointers (78) Stack (76) Company-Facebook (75) BST (72) Graph Algorithm (72) Time Complexity (69) Greedy Algorithm (68) Interval (63) Company - Google (62) Geometry Algorithm (61) Interview Corner (61) LeetCode - Extended (61) Union-Find (60) Trie (58) Advanced Data Structure (56) List (56) Priority Queue (53) Codility (52) ComProGuide (50) LeetCode Hard (50) Matrix (50) Bisection (48) Segment Tree (48) Sliding Window (48) USACO (46) Space Optimization (45) Company-Airbnb (41) Greedy (41) Mathematical Algorithm (41) Tree - Post-Order (41) ACM-ICPC (40) Algorithm Interview (40) Data Structure Design (40) Graph (40) Backtracking (39) Data Structure (39) Jobdu (39) Random (39) Codeforces (38) Knapsack (38) LeetCode - DP (38) Recursive Algorithm (38) String Algorithm (38) TopCoder (38) Sort (37) Introduction to Algorithms (36) Pre-Sort (36) Beauty of Programming (35) Must Known (34) Binary Search Tree (33) Follow Up (33) prismoskills (33) Palindrome (32) Permutation (31) Array (30) Google Code Jam (30) HDU (30) Array O(N) (29) Logic Thinking (29) Monotonic Stack (29) Puzzles (29) Code - Detail (27) Company-Zenefits (27) Microsoft 100 - July (27) Queue (27) Binary Indexed Trees (26) TreeMap (26) to-do-must (26) 1point3acres (25) GeeksQuiz (25) Merge Sort (25) Reverse Thinking (25) hihocoder (25) Company - LinkedIn (24) Hash (24) High Frequency (24) Summary (24) Divide and Conquer (23) Proof (23) Game Theory (22) Topological Sort (22) Lintcode - Review (21) Tree - Modification (21) Algorithm Game (20) CareerCup (20) Company - Twitter (20) DFS + Review (20) DP - Relation (20) Brain Teaser (19) DP - Tree (19) Left and Right Array (19) O(N) (19) Sweep Line (19) UVA (19) DP - Bit Masking (18) LeetCode - Thinking (18) KMP (17) LeetCode - TODO (17) Probabilities (17) Simulation (17) String Search (17) Codercareer (16) Company-Uber (16) Iterator (16) Number (16) O(1) Space (16) Shortest Path (16) itint5 (16) DFS+Cache (15) Dijkstra (15) Euclidean GCD (15) Heap (15) LeetCode - Hard (15) Majority (15) Number Theory (15) Rolling Hash (15) Tree Traversal (15) Brute Force (14) Bucket Sort (14) DP - Knapsack (14) DP - Probability (14) Difficult (14) Fast Power Algorithm (14) Pattern (14) Prefix Sum (14) TreeSet (14) Algorithm Videos (13) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Combination (13) Computational Geometry (13) DP - Digit (13) LCA (13) LeetCode - DFS (13) Linked List (13) Long Increasing Sequence(LIS) (13) Math-Divisible (13) Reservoir Sampling (13) mitbbs (13) Algorithm - How To (12) Company - Microsoft (12) DP - Interval (12) DP - Multiple Relation (12) DP - Relation Optimization (12) LeetCode - Classic (12) Level Order Traversal (12) Prime (12) Pruning (12) Reconstruct Tree (12) Thinking (12) X Sum (12) AOJ (11) Bit Mask (11) Company-Snapchat (11) DP - Space Optimization (11) Dequeue (11) Graph DFS (11) MinMax (11) Miscs (11) Princeton (11) Quick Sort (11) Stack - Tree (11) 尺取法 (11) 挑战程序设计竞赛 (11) Coin Change (10) DFS+Backtracking (10) Facebook Hacker Cup (10) Fast Slow Pointers (10) HackerRank Easy (10) Interval Tree (10) Limited Range (10) Matrix - Traverse (10) Monotone Queue (10) SPOJ (10) Starting Point (10) States (10) Stock (10) Theory (10) Tutorialhorizon (10) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Maze (9) Median (9) O(32N) (9) Quick Select (9) Stack Overflow (9) System Design (9) Tree - Conversion (9) Use XOR (9) Book Notes (8) Company-Amazon (8) DFS+BFS (8) DP - States (8) Expression (8) Longest Common Subsequence(LCS) (8) One Pass (8) Quadtrees (8) Traversal Once (8) Trie - Suffix (8) 穷竭搜索 (8) Algorithm Problem List (7) All Sub (7) Catalan Number (7) Cycle (7) DP - Cases (7) Facebook Interview (7) Fibonacci Numbers (7) Flood fill (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Inversion (7) Kadane’s Algorithm (7) Manacher (7) Morris Traversal (7) Multiple Data Structures (7) Normalized Key (7) O(XN) (7) Radix Sort (7) Recursion (7) Sampling (7) Suffix Array (7) Tech-Queries (7) Tree - Serialization (7) Tree DP (7) Trie - Bit (7) 蓝桥杯 (7) Algorithm - Brain Teaser (6) BFS - Priority Queue (6) BFS - Unusual (6) Classic Data Structure Impl (6) DP - 2D (6) DP - Monotone Queue (6) DP - Unusual (6) DP-Space Optimization (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Local MinMax (6) MST (6) Minimum Spanning Tree (6) Number - Reach (6) Parentheses (6) Pre-Sum (6) Probability (6) Programming Pearls (6) Rabin-Karp (6) Reverse (6) Scan from right (6) Schedule (6) Stream (6) Subset Sum (6) TSP (6) Xpost (6) n00tc0d3r (6) reddit (6) AI (5) Abbreviation (5) Anagram (5) Art Of Programming-July (5) Assumption (5) Bellman Ford (5) Big Data (5) Code - Solid (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) DFS - Multiple (5) DFS+DP (5) DP - Multi-Dimension (5) DP-Multiple Relation (5) Eulerian Cycle (5) Graph - Unusual (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) LogN (5) Manhattan Distance (5) Matrix Chain Multiplication (5) N Queens (5) Pre-Sort: Index (5) Quick Partition (5) Quora (5) Randomized Algorithms (5) Resources (5) Robot (5) SPFA(Shortest Path Faster Algorithm) (5) Shuffle (5) Sieve of Eratosthenes (5) Strongly Connected Components (5) Subarray Sum (5) Sudoku (5) Suffix Tree (5) Swap (5) Threaded (5) Tree - Creation (5) Warshall Floyd (5) Word Search (5) jiuzhang (5)

Popular Posts