2014-05-10 22:58
原题:
Three points are given A(x1, y1), B(x2, y2), C(x3, y3). Write a method returning an array of points (x, y) inside the triangle ABC.
题目:给定三个点,找出所有这三点组成的三角形内的整点。(不能组成三角形也无所谓,结果为空即可。)
解法:出题者没有说是整点,但如果不是整点,就有无穷多个了。求整点的个数可以用Pick定律的公式。要求出所有整点的话,我的方法是找出一个内部的整点,然后向四个方向进行DFS,直到找出所有点。搜索过程中,需要判断点是否在三角形内部。我的判断方法是计算面积。对于整数问题,计算公式不要引入浮点数,误差是不必要的。所以海伦公式不可行,用行列式计算面积更为方便、准确。
代码:
1 // http://www.careercup.com/question?id=5120588943196160 2 #include <iostream> 3 #include <unordered_set> 4 #include <vector> 5 using namespace std; 6 7 struct Point { 8 int x; 9 int y; 10 Point(int _x = 0, int _y = 0): x(_x), y(_y) {}; 11 }; 12 13 struct hashFunctor { 14 size_t operator () (const Point &p) { 15 return p.x * 10000 + p.y; 16 }; 17 }; 18 19 struct equalFunctor { 20 bool operator () (const Point &p1, const Point &p2) { 21 return p1.x == p2.x && p1.y == p2.y; 22 }; 23 }; 24 25 typedef unordered_set<Point, hashFunctor, equalFunctor> point_set; 26 27 int twoArea(int x1, int y1, int x2, int y2, int x3, int y3) 28 { 29 return abs(x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2)); 30 } 31 32 bool inside(int x[3], int y[3], int px, int py) 33 { 34 int sum = 0; 35 36 sum += twoArea(x[0], y[0], x[1], y[1], px, py); 37 sum += twoArea(x[1], y[1], x[2], y[2], px, py); 38 sum += twoArea(x[2], y[2], x[0], y[0], px, py); 39 return sum == twoArea(x[0], y[0], x[1], y[1], x[2], y[2]); 40 } 41 42 void DFS(int x[3], int y[3], int px, int py, point_set &um, point_set &visited) 43 { 44 static const int dir[4][2] = { 45 {-1, 0}, 46 {+1, 0}, 47 {0, -1}, 48 {0, +1} 49 }; 50 int i; 51 int newx, newy; 52 53 visited.insert(Point(px, py)); 54 um.insert(Point(px, py)); 55 56 for (i = 0; i < 4; ++i) { 57 newx = px + dir[i][0]; 58 newy = py + dir[i][1]; 59 if (visited.find(Point(newx, newy)) == visited.end() && 60 inside(x, y, newx, newy)) { 61 DFS(x, y, newx, newy, um, visited); 62 } 63 } 64 } 65 66 void insidePoints(int x[3], int y[3], vector<Point> &points) 67 { 68 point_set um; 69 point_set visited; 70 int mx, my; 71 72 mx = (x[0] + x[1] + x[2]) / 3; 73 my = (y[0] + y[1] + y[2]) / 3; 74 DFS(x, y, mx, my, um, visited); 75 76 point_set::const_iterator usit; 77 for (usit = um.begin(); usit != um.end(); ++usit) { 78 points.push_back(Point(usit->x, usit->y)); 79 } 80 um.clear(); 81 visited.clear(); 82 } 83 84 int main() 85 { 86 int x[3]; 87 int y[3]; 88 vector<Point> points; 89 int i; 90 int n; 91 92 while (cin >> x[0] >> y[0]) { 93 cin >> x[1] >> y[1]; 94 cin >> x[2] >> y[2]; 95 insidePoints(x, y, points); 96 n = (int)points.size(); 97 for (i = 0; i < n; ++i) { 98 cout << points[i].x << ' ' << points[i].y << endl; 99 } 100 points.clear(); 101 } 102 103 return 0; 104 }