HDU 2108 逆时针给出多边形的顶点,判断是否为凸多边形,水题
下面是别人解题报告的链接,很详细,写的很好
http://blog.csdn.net/chl_3205/article/details/8520597
下面贴我的代码
1 #include <cstdio> 2 struct point 3 { 4 int x,y; 5 } p[100005]; 6 bool checkDir(point p0,point p1,point p2) 7 { 8 if((p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y) * (p2.x-p0.x) > 0) 9 return true; 10 else return false; 11 } 12 int main() 13 { 14 // freopen("in.cpp","r",stdin); 15 int n; 16 while(scanf("%d",&n),n) 17 { 18 for(int i=0; i<n; ++i) 19 scanf("%d%d",&p[i].x,&p[i].y); 20 bool flag = true; 21 bool cur = checkDir(p[0],p[1],p[2]); 22 for(int i=1; i<n; ++i) 23 { 24 bool f = checkDir(p[i],p[(i+1)%n],p[(i+2)%n]); 25 if(f != cur) 26 { 27 flag = false; 28 break; 29 } 30 } 31 if(flag ) printf("convex\n"); 32 else printf("concave\n"); 33 } 34 return 0; 35 }
虽然这是一个水题,但是其中的思想与Andrew算法求凸包的思想是一样的。。。。
Andrew算法求凸包的思想大概是:先将所有点按坐标x从小到大排序,x相同按y从小到大排序。
然后按排好顺序的序列顺序前进,是往左走的就加入凸包,出现往右走的就回溯剔除点,直到往左走。这样求出下半个凸包。
再逆序前进一遍,同理,求出上半个凸包。刘汝佳的白书中有介绍。
下面的代码本质上是在求凸包,但是也可以用来判断该多边形是否为凸多边形。同时不要求点是按逆时针顺序给出的。
1 //求凸包Andrew扫描算法,复杂度主要为排序O(n*logn),扫描为O(n) 2 #include <cstdio> 3 #include <algorithm> 4 #define INF 0x7fffffff 5 using namespace std; 6 struct point 7 { 8 int x,y; 9 bool operator <(const point & other) const 10 { 11 if(x < other.x) 12 return true; 13 if(x == other.x && y < other.y) 14 return true; 15 return false; 16 }; 17 } p[330],convex[330]; 18 bool checkDir(point p0,point p1,point p2) 19 { 20 if((p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y) * (p2.x-p0.x) <= 0) 21 return true; 22 else return false; 23 } 24 int main() 25 { 26 // freopen("in.cpp","r",stdin); 27 int n; 28 while(scanf("%d",&n) ,n) 29 { 30 for(int i=0; i<n; ++i) 31 scanf("%d%d",&p[i].x,&p[i].y); 32 sort(p,p+n); 33 int m=0; 34 for(int i=0; i<n; ++i) 35 { 36 while(m > 1 && checkDir(convex[m-2],convex[m-1],p[i]) ) --m; 37 convex[m++] = p[i]; 38 } 39 int k =m; 40 for(int i=n-2; i>=0; --i) 41 { 42 while(m > k && checkDir(convex[m-2],convex[m-1],p[i]) ) --m; 43 convex[m++] = p[i]; 44 } 45 if(n >1) --m; 46 if(m == n) printf("convex\n"); 47 else printf("concave\n"); 48 } 49 return 0; 50 }
求凸包有很多算法吧,应该,下面是详细介绍一种貌似叫Graham算法求凸包,但是该算法数值稳定性没有Andrew算法好,它还要求角的余弦值,排序。