您的位置:首页 > 其它

HDU1392Surround the Trees(凸包判断 + 求周长)

2016-03-18 14:53 387 查看
http://www.cnblogs.com/hmhard/archive/2013/02/05/2893035.html 这是判断三角区域那块写的不好。

判断凸包的方法:

1、将所有点按照y从小到大排序,x从小到大排序

2、现将前两个点放入栈中,然后判断下一个点在这两个点组成的线段的左边还是右边,左边的话,直接加入栈中, 如果在右边的话,就不行了,为了让这个点行,所以栈顶元素出栈,然后在判断栈中前两个组成的线段 跟 这个点个关系...其实这个关键就是不顾一切的让这个点进栈,即使把栈中的元素全部弹出来(当然不会,会留有一个)

3、弄完之后其实最大的那个点已经在栈中了,然后在反过来,从这个最大的开始像之前一样判断。

4、最后弄完,栈顶和栈底都是最小的那个元素。

---------------------------------------------------

三角区域判断:

借助向量,对于OA 和 OB ,如果 Xa Yb - XbYa > 0,OB在OA的右侧,如果小于0,OB在OA的左侧,如果相等共线

---------------------------------------------------------

HD1392

题意:N个点,然后输入N个点的坐标,问形成凸包的周长

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
struct Node
{
int x, y;
};
Node node[110], ch[110];
int cmp(Node tempx, Node tempy)
{
if(tempx.y == tempy.y)
return tempx.x < tempy.x;
return tempx.y < tempy.y;
}
int xmult(Node p1, Node p2, Node p3)
{
return (p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y);
}
double dist(Node p1, Node p2)
{
return sqrt( (p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y) );
}
int andrew(int n)
{
int len, top = 1;
ch[0] = node[0];
ch[1] = node[1];
for(int i = 2; i < n; i++)
{
while(top && xmult(ch[top - 1], ch[top], node[i]) <= 0) // 保证top>0的情况下才能出栈,因为top等于0,出栈就空了
top--;
ch[ ++top ] = node[i];
}
len = top;
ch[++top] = node[n - 2];
for(int i = n - 3; i >= 0; i--)
{
while(top != len && xmult(ch[top - 1], ch[top], node[i]) <= 0)  // 这个也要保证当前栈最小是len,如果 > len可以出栈
top--;
ch[ ++top ] = node[i];
}
return top;
}
int main()
{
int n;
while (scanf("%d", &n) != EOF && n)
{
for(int i = 0; i < n; i++)
scanf("%d%d", &node[i].x, &node[i].y);
sort(node, node + n, cmp);
int top = andrew(n);
double ans = 0;
//for(int i = 0; i <= top; i++)
//    cout << ch[i].x << " " << ch[i].y << endl;
for (int i = 1 ; i < top ; i ++)
ans += dist(ch[i - 1] , ch[i]);
if (top > 2)  // 如果两个点以上还要计算一下栈底 和 次栈底的距离
ans += dist(ch[0], ch[top - 1]);
printf("%.2lf\n" , ans);
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: