您的位置:首页 > 其它

[Swust OJ 249]--凸包面积

2015-05-30 21:09 309 查看
题目链接:'target='_blank'>http://acm.swust.edu.cn/problem/0249/
麦兜是个淘气的孩子。一天,他在玩钢笔的时候把墨水洒在了白色的墙上。再过一会,麦兜妈就要回来了,麦兜为了不让妈妈知道这件事情,就想用一个白色的凸多边形把墙上的墨点盖住。你能告诉麦兜最小需要面积多大的凸多边形才能把这些墨点盖住吗?
现在,给出了这些墨点的坐标,请帮助麦兜计算出覆盖这些墨点的最小凸多边形的面积。
Description

多组测试数据。第一行是一个整数T,表明一共有T组测试数据。
每组测试数据的第一行是一个正整数N(0<N<=105),表明了墨点的数量。接下来的N行每行包含了两个整数Xi和Yi(0<=Xi,Yi<=2000),表示每个墨点的坐标。每行的坐标间可能包含多个空格。
Input

每行输出一组测试数据的结果,只需输出最小凸多边形的面积。面积是个实数,小数点后面保留一位即可,不需要多余的空格。
Output

1
2
3
4
5
6
7
8
9

2
4
00
10
01
11
2
00
01

SampleInput

1
2

1.0
0.0

SampleOutput

Hint

就是一个凸包的点集覆盖求最小覆盖面积~~~
一个告诉多边形顶点坐标的面积求法(按顺序给出)
area+=(pos.x*tmp.y-pos.y*tmp.x)/2.0;(pos当前点,tmp下一个点,最后一个点和第一个点在来一次)


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<stack>
#include<cmath>
usingnamespacestd;
structnode{
doublex,y;
}point[110],pos,tmp;
doubledis(nodea,nodeb){
returnpow((a.x-b.y),2)+pow((a.y-b.y),2);
}
//按点集分布排序,利用向量平行关系判断(极角排序),角度相同则距离小的在前面
boolcmp(nodea,nodeb){
doublepovit=(a.x-pos.x)*(b.y-pos.y)-(b.x-pos.x)*(a.y-pos.y);
if(povit>0||!povit&&(dis(a,pos)<dis(b,pos)))
returntrue;
returnfalse;
}
//当前点是否在点集左侧,利用叉乘比较3个点两条线的斜率关系
boolturn_left(nodep1,nodep2,nodep3){
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;
}
intmain(){
inti,sign,n,t;
doublearea;
cin>>t;
while(t--){
cin>>n;
for(i=0;i<n;i++)
cin>>point[i].x>>point[i].y;
if(n<=2){
cout<<"0.0\n";
continue;
}
stack<node>Q;
sign=0;
pos=point[0];
for(i=1;i<n;i++){
if(pos.y==point[i].y&&pos.x>point[i].x||point[i].y<pos.y){
pos=point[i];
sign=i;
}
}
swap(point[0],point[sign]);
sort(point+1,point+n,cmp);
Q.push(point[0]),Q.push(point[1]),Q.push(point[2]);
for(i=3;i<n;i++){
while(!Q.empty()){
tmp=Q.top();
Q.pop();
if(turn_left(tmp,Q.top(),point[i])){
Q.push(tmp);
break;
}
}
Q.push(point[i]);
}
area=0;
tmp=Q.top(),Q.pop();
area+=(pos.x*tmp.y-pos.y*tmp.x)/2.0;
while(!Q.empty()){
area+=(tmp.x*Q.top().y-tmp.y*Q.top().x)/2.0;
tmp=Q.top();
Q.pop();
}
printf("%.1lf\n",fabs(area));
}
return0;
}


ViewCode

主要的地方就是利用向量平行关系,按点集的离散化排序

(没说清楚~~~看凸包的简单概念吧http://www.cnblogs.com/zyxStar/p/4540984.html),

判断下一个的点能否覆盖已选取的点~~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: