您的位置:首页 > 其它

poj1228 - Grandpa's Estate

2012-08-27 10:18 309 查看
                                想看更多的解题报告:http://blog.csdn.net/wangjian8006/article/details/7870410

                                  转载请注明出处:http://blog.csdn.net/wangjian8006

 题目大意:原本有一些点围成了一个凸多边形,你不知道原来是什么样子的,现在又 给出一些点,确保这些点都是凸包上的点(不会在以前的凸包的里面), 现在问你这些点围成的形状是否可以确定原来那些点围成的凸多边形

 解题思路:由于我们知道现在给的点全是凸包上的点,所以我们看现在的这个凸包的【顶点】中间有没有其他的点,如果至少有一点的话,那么这条边就是确定的了,不会再有改变。

 但是如果没有其他点,那么两个顶点是不能确定原来的那个凸多边形的形状的,因为两个点之间以前还可以存在某些点没在这条边上。

 所以我们只需要将给的凸包点算出凸包顶点,然后再判断两相邻顶点之间有没其他点就可以了

 

/*
Memory 188K
Time   16MS
*/
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define MAXV 1010
#define INF 1e8

struct Point{
double x,y;
}point[MAXV],tmp;

int n,d[MAXV],dtop;

double distance(double x1,double y1,double x2,double y2){
double dis=(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
return sqrt(dis);
}

double chaji(struct Point a1,struct Point b1,struct Point a2,struct Point b2){  //求<a1,b1>向量和<a2,b2>向量的叉积
double x1=b1.x-a1.x;
double y1=b1.y-a1.y;
double x2=b2.x-a2.x;
double y2=b2.y-a2.y;
return x1*y2-x2*y1;
}

int cmp(const void *p1,const void *p2){
struct Point *a=(struct Point *)p1;
struct Point *b=(struct Point *)p2;
double flag=chaji(point[0],*a,point[0],*b);
if(flag>0)   return -1;
else if(!flag && distance((a->x),(a->y),point[0].x,point[0].y)<distance((b->x),(b->y),point[0].x,point[0].y))
return -1;
return 1;
}

int findminp(){
int i,v;
double ymin=INF,xmin=INF;
for(i=0;i<n;i++)
if(point[i].y<ymin)
v=i,ymin=point[i].y;

for(i=0;i<n;i++)
if(point[i].y==ymin && point[i].x<xmin)
v=i,xmin=point[i].x;
return v;
}

void graham(){
int i;
dtop=0;
d[dtop++]=0;
d[dtop++]=1;
for(i=2;i<n;i++){
while(chaji(point[d[dtop-2]],point[d[dtop-1]],point[d[dtop-1]],point[i])<0) dtop--;
d[dtop++]=i;
}
}
int main(){
int t,h,i,j,flag,sum;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(i=0;i<n;i++) scanf("%lf%lf",&point[i].x,&point[i].y);
if(n<=5) {printf("NO\n");continue;}
h=findminp();
tmp=point[0];
point[0]=point[h];
point[h]=tmp;
qsort(point+1,n-1,sizeof(point[0]),cmp);
graham();			//求出凸包

flag=1;				//看凸包上【顶点】的中间有没有其他点,如果有一条没有就是NO
sum=0;
for(i=1;i<dtop;i++){
for(j=0;j<n;j++)
if(j!=d[i] && j!=d[i-1] && !chaji(point[d[i-1]],point[d[i]],point[d[i-1]],point[j])){
break;
}
if(j==n) sum++;
}
for(j=0;j<n;j++)
if(j!=d[0] && j!=d[i-1] && !chaji(point[d[0]],point[d[i-1]],point[d[0]],point[j])){
break;
}
if(j==n) sum++;

if(sum>0) flag=0;

if(flag) printf("YES\n");
else printf("NO\n");
}
return 0;
}


 

 

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