标签:
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 12204 | Accepted: 3430 |
Description
Input
Output
Sample Input
1 6 0 0 1 2 3 4 2 0 2 4 5 0
Sample Output
NO
题目难懂.
题意:稳定凸包问题:给出n个点,问形成的凸包是否"稳定"。
所谓稳定就是判断能不能在原有凸包上加点,得到一个更大的凸包,并且这个凸包包含原有凸包上的所有点。
这个解释感觉容易懂,引自:http://blog.csdn.net/acdreamers/article/details/10023615/
我的看法其实就是一条边上要除了顶点外至少还要一个点.那样的话才会稳定.
以我之拙见。。网上的解法是有问题的。。给出我的解法和别人的一组测试数据。POJ的数据可能水了点..网上的解法很多都是将在凸包上边上但不是顶点的点加进去。然后再用两个叉积条件判断。
我是直接枚举每条边,然后枚举所有点,除了顶点之外至少还要有一个点在边上才行(题目说了点都在凸包顶点或者边上,,这样更说明了如果用网上的解法去求凸包是没有意义的,因为已经排好序了,所有的点再加一次,Stack应该就是p了)。
还要加个条件就是点数不能小于6,因为就算是三角形都至少需要6个点才稳定。
测试数据:
1
6
0 0 1 1 2 2 3 3 2 3 0 3
NO
#include <iostream> #include <cstdio> #include <cstring> #include <math.h> #include <algorithm> #include <stdlib.h> using namespace std; const int N = 1005; const double eps = 1e-8; struct Point { int x,y; }p[N],Stack[N]; struct Line{ Point a,b; }line; int n; int cross(Point a,Point b,Point c){ return (a.x-c.x)*(b.y-c.y)-(a.y-c.y)*(b.x-c.x); } double dis(Point a,Point b){ return sqrt((double)((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y))); } int cmp(Point a,Point b){ if(cross(a,b,p[0])>0) return 1; if(cross(a,b,p[0])==0&&dis(b,p[0])-dis(a,p[0])>eps) return 1; return 0; } bool Graham(){ int k=0; for(int i=1;i<n;i++){ if(p[i].y<p[k].y||(p[i].y==p[k].y)&&(p[i].x<p[k].x)) k=i; } swap(p[0],p[k]); sort(p+1,p+n,cmp); int top =2; Stack[0] = p[0]; Stack[1] = p[1]; Stack[2] = p[2]; for(int i=3;i<n;i++){ while(top>=1&&cross(p[i],Stack[top],Stack[top-1])>=0) top--; Stack[++top] = p[i]; } int cnt ; Stack[top+1] = Stack[0]; for(int i=0;i<=top;i++){ line.a = Stack[i]; line.b = Stack[i+1]; cnt =0; for(int j=0;j<n;j++){ if(line.a.x == p[j].x && line.a.y == p[j].y) continue; ///除去自身 if(line.b.x == p[j].x && line.b.y == p[j].y) continue; if(cross(line.a,line.b,p[j])==0){ cnt++; break; } } if(cnt==0) return false; } return true; } int main() { int tcase; scanf("%d",&tcase); while(tcase--){ scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%d%d",&p[i].x,&p[i].y); } if(n<6){ printf("NO\n");continue; } bool ans = Graham(); if(ans) printf("YES\n"); else printf("NO\n"); } return 0; }
标签:
原文地址:http://www.cnblogs.com/liyinggang/p/5451222.html