1
2
3
4
5
6
7
8
9
|
2
4
0 0
1 0
0 1
1 1
2
0 0
0 1
|
1
2
|
1.0
0.0
|
area += (pos.x*tmp.y - pos.y*tmp.x) / 2.0;(pos当前点,tmp下一个点,最后一个点和第一个点在来一次)
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<stack> 5 #include<cmath> 6 using namespace std; 7 struct node{ 8 double x, y; 9 }point[110], pos, tmp; 10 double dis(node a, node b){ 11 return pow((a.x - b.y), 2) + pow((a.y - b.y), 2); 12 } 13 //按点集分布排序,利用向量平行关系判断(极角排序),角度相同则距离小的在前面 14 bool cmp(node a, node b){ 15 double povit = (a.x - pos.x)*(b.y - pos.y) - (b.x - pos.x)*(a.y - pos.y); 16 if (povit > 0 || !povit && (dis(a, pos) < dis(b, pos))) 17 return true; 18 return false; 19 } 20 //当前点是否在点集左侧,利用叉乘比较3个点两条线的斜率关系 21 bool turn_left(node p1, node p2, node p3){ 22 return (p2.x*p1.y + p3.x*p2.y + p1.x*p3.y - p3.x*p1.y - p1.x*p2.y - p2.x*p3.y) > 0 ? true : false; 23 } 24 int main(){ 25 int i, sign, n, t; 26 double area; 27 cin >> t; 28 while (t--){ 29 cin >> n; 30 for (i = 0; i < n; i++) 31 cin >> point[i].x >> point[i].y; 32 if (n <= 2){ 33 cout << "0.0\n"; 34 continue; 35 } 36 stack<node> Q; 37 sign = 0; 38 pos = point[0]; 39 for (i = 1; i < n; i++){ 40 if (pos.y == point[i].y&&pos.x>point[i].x || point[i].y < pos.y){ 41 pos = point[i]; 42 sign = i; 43 } 44 } 45 swap(point[0], point[sign]); 46 sort(point + 1, point + n, cmp); 47 Q.push(point[0]), Q.push(point[1]), Q.push(point[2]); 48 for (i = 3; i < n; i++){ 49 while (!Q.empty()){ 50 tmp = Q.top(); 51 Q.pop(); 52 if (turn_left(tmp, Q.top(), point[i])){ 53 Q.push(tmp); 54 break; 55 } 56 } 57 Q.push(point[i]); 58 } 59 area = 0; 60 tmp = Q.top(), Q.pop(); 61 area += (pos.x*tmp.y - pos.y*tmp.x) / 2.0; 62 while (!Q.empty()){ 63 area += (tmp.x*Q.top().y - tmp.y*Q.top().x) / 2.0; 64 tmp = Q.top(); 65 Q.pop(); 66 } 67 printf("%.1lf\n", fabs(area)); 68 } 69 return 0; 70 }
主要的地方就是利用向量平行关系,按点集的离散化排序
(没说清楚~~~看凸包的简单概念吧http://www.cnblogs.com/zyxStar/p/4540984.html),
判断下一个的点能否覆盖已选取的点~~