pku 1228 Grandpa's Estate 凸多边形的唯一性(凸包)

题意:
一个凸多边形的边界上有若干木桩,现丢失部分木桩,问由剩下的木桩能否唯一确定这个多边形

解法:
首先能够唯一确定的条件是由剩下的木桩确定的凸包的每条边上至少包含3个木桩,这个自己画图比划下就知道了- -
然后就是求一个凸包了。在这种坐标都是整数的情况下,凸包最好不要用atan2函数,而是用叉积来比较。我特地用纯C写了个,有要的童鞋可以拿去当模板
有个阴险的地方,就是测试数据只有3个点,而且3点一线。。。你懂的

代码
 1#  include <stdio.h>
 2#  include <stdlib.h>
 3# define N 1200
 4# define cross(x1,y1,x2,y2) ((x1)*(y2)-(x2)*(y1))
 5# define min(a,b) ((a)<(b)?(a):(b))
 6# define max(a,b) ((a)>(b)?(a):(b))
 7typedef struct
 8{
 9    int x,y;
10}
point;
11int n,c;
12point data[N],ans[N],std;
13int dis(point *pos)
14{
15    return (pos->x-std.x)*(pos->x-std.x)+(pos->y-std.y)*(pos->y-std.y);
16}

17int isin(point *a,point *b,point *pos)
18{
19    if(pos->x>max(a->x,b->x)||pos->x<min(a->x,b->x)||pos->y>max(a->y,b->y)||pos->y<min(a->y,b->y)) return 0;
20    else if(cross(pos->x-a->x,pos->y-a->y,b->x-a->x,b->y-a->y)!=0return 0;
21    else return 1;
22}

23int cmp(const void *a,const void *b)
24{
25    point *aa=(point *)a,*bb=(point *)b;
26    if(cross(bb->x-std.x,bb->y-std.y,aa->x-std.x,aa->y-std.y))
27            return cross(bb->x-std.x,bb->y-std.y,aa->x-std.x,aa->y-std.y);
28    else 
29            return dis(aa)-dis(bb);
30}

31void sort()
32{
33    int i;
34    int x=0xfffffff,y=0xfffffff;
35    for(i=0;i<n;i++)
36        if(data[i].y<y||data[i].y==y&&data[i].x<x)
37            y=data[i].y,x=data[i].x;
38    std.x=x;
39    std.y=y;
40    qsort(data,n,sizeof(point),cmp);
41}

42void build()
43{
44    int i;
45    c=0;
46    sort();
47    for(i=0;i<n;i++)
48    {
49        while(c>=2&&cross(data[i].x-ans[c-1].x,data[i].y-ans[c-1].y,ans[c-1].x-ans[c-2].x,ans[c-1].y-ans[c-2].y)>=0) c--;
50        ans[c++]=data[i];
51    }

52    if(c>0) ans[c++]=ans[0];
53}

54int chk()
55{
56    int i;
57    for(i=0;i<c-1;i++)
58    {
59        int count=0,j;
60        for(j=0;j<n;j++)
61            if(isin(&ans[i],&ans[i+1],&data[j]))
62                count++;
63        if(count<3return 0;
64    }

65    return 1;
66}

67int main()
68{
69    int test;
70    scanf("%d",&test);
71    while(test--)
72    {
73        int i;
74        scanf("%d",&n);
75        for(i=0;i<n;i++)
76            scanf("%d %d",&data[i].x,&data[i].y);
77        build();
78        if(c>3&&chk()) printf("YES\n");
79        else printf("NO\n");
80    }

81    return 0;
82}

83

posted on 2011-01-15 02:27 yzhw 阅读(274) 评论(0)  编辑 收藏 引用 所属分类: geometry&phycise


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2011年1月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
303112345

导航

统计

公告

统计系统

留言簿(1)

随笔分类(227)

文章分类(2)

OJ

最新随笔

搜索

积分与排名

最新评论

阅读排行榜