您的位置:首页 > 其它

usc week 5 计算几何(包含凸包) 队内练习题

2012-04-25 17:25 211 查看
第一题 shape of hdu   http://acm.hdu.edu.cn/showproblem.php?pid=2108
这个 看样子 大嘴鸟的我还得优化一下~~为什么别人的代码都是600多b为什么我的写了2600多b呢~~~
算法:
过多边形任意一边做一条直线,如果其他各顶点都在这条直线的同侧,则把这个多边形叫做凸多边形

我采用的是
(1)输入数据
(2)以相邻两点作为直线进行判断存在三种情况(我是利用高中的两点式求直线方程的~~)
1平行x轴直线
2平行y轴直线
3既不平行x轴也不平行y轴
(3)判断除了做这两条直线上的点,其他的点都是否在这条直线上的一边。
判断是否满足条件~~~

贴上代码~~
#include<stdio.h>

struct stu{

float x,y;

}  point[1000000];
int n,sum1,sum2,sum,flag2,flag1,flag;     //flag 是用来判断 特殊情况 平行x轴,y轴。

int judge(void);
int judgex(int i);          //判断平行x轴情况
int judgey(int i);          //判断平行y轴情况

int main()
{
int i,t,result;
while(scanf("%d",&n)&&n!=0){
//输入数据
for(i=1;i<=n;i++)
scanf("%f %f",&point[i].x,&point[i].y);
point[i].x=point[1].x;
point[i].y=point[1].y;
sum1=sum2=sum=0;
result=judge();
if(result==1)printf("convex\n");      //根据judge的返回值来判断是否是凸包
else printf("concave\n");

}

}

int judge(void)
{
int recycle,i,j;
float a,b;
recycle=n;

for(j=1;j<=recycle;j++){                  //判断所有点是否在一条直线的同侧
flag1=flag2=flag=0;
if(point[j].x-point[j+1].x==0){judgey(j);if(flag==1)sum++;/*printf("sum=%d\n",sum);*/continue;      }
if(point[j].y-point[j+1].y==0){judgex(j);if(flag==1)sum++;/*printf("sum=%d\n",sum);*/ continue;      }

a=(point[j].y-point[j+1].y)/(point[j].x-point[j+1].x);
b=point[j].y-a*point[j].x;
//printf("a=%f b=%f\n",a,b);   //
sum1=sum2=0;
for(i=1;i<=recycle;i++)
{  if(i==j||i==j+1)
{
sum1++;sum2++;   //printf("sum1=%d sum2=%d\n",sum1,sum2);    //
continue;
}
if(a*point[i].x-point[i].y+b>=0) sum1++;
if(a*point[i].x-point[i].y+b<=0) sum2++;
//printf("sum1=%d sum2=%d\n",sum1,sum2);        //
}
if(sum1==n||sum2==n) sum++;
// printf("sum=%d\n",sum);
}

// printf("sum=%d\n",sum);                          //
if(sum==n)return 1;
else return 0;

}

int judgex(int i)
{
int j;
for(j=1;j<=n;j++)
{
if(point[i].y>=point[j].y)flag1++;
if(point[i].y<=point[j].y)flag2++;
}
if(flag1==n||flag2==n)flag=1;
}
int judgey(int i)
{
int j;
for(j=1;j<=n;j++)
{
if(point[i].x>=point[j].x)flag1++;
if(point[i].x<=point[j].x)flag2++;
}
if(flag1==n||flag2==n)flag=1;
}

进行的是对内赛的第二题 http://openoj.awaysoft.com:8080/judge/contest/view.action?cid=173#problem/B
此乃poj上的计算几何问题
要注意的是最后的面积可能超出结果,所以采用longlong形式存储
算法(1)
1 先一次将每次移动的坐标输入进去
2 然后队坐标进行差乘运算

Area of polygon

The area of a polygon with vertices (x 1, y 1), ..., (x n, y n) is equal to the determinant:1 | x1 x2 ... xn |--- | |2 | y1 y2 ... yn |

where the determinate is defined to be similar to the 2 by 2 determinant: x1 y2 + x2y3+ ... + xn y1 - y1 x2 - y2x3 - ... - yn x1
3 得出最后的结果

贴代码:

#include<stdio.h>

structnode{
int x,y;
}point[1000010];

void map(void);
int i;

int main()
{
int  n;
char num;
scanf("%d",&n);
// printf("%d\n",n);
getchar();
while(n--){
i=0;
point[i].x=point[i].y=0;
while(scanf("%c",&num)&&num!='5'){
i++;

//  printf("i=%d\n",i);
switch(num){
case '8':point[i].x=point[i-1].x;point[i].y=point[i-1].y+1;break;
case '2':point[i].x=point[i-1].x;point[i].y=point[i-1].y-1; break;
case '6':point[i].x=point[i-1].x+1; point[i].y=point[i-1].y;break;
case '4':point[i].x=point[i-1].x-1; point[i].y=point[i-1].y;break;
case '1':point[i].x=point[i-1].x-1; point[i].y=point[i-1].y-1;break;
case '3':point[i].x=point[i-1].x+1; point[i].y=point[i-1].y-1;break;
case '7':point[i].x=point[i-1].x-1; point[i].y=point[i-1].y+1;break;
case '9':point[i].x=point[i-1].x+1; point[i].y=point[i-1].y+1;
}
// printf("x=%d y=%d\n",point[i].x,point[i].y);

}
getchar();
point[i].x=point[i].y=0;
//    printf("x=%d y=%d\n",point[i].x,point[i].y);
map();
}

}
void map(void){
//  printf("ii=%d",i);
int j=0;
long long s=0;
if(i==0)printf("0\n");
else {  for(j=0;j<=i-1;j++)
{
s+=long (point[j].x*point[j+1].y-point[j].y*point[j+1].x);
//  printf("%d\n",s);
}
if(s<0)s=0-s;

if(s%2==1)printf("%I64d.5\n",s/2);
else printf("%I64d\n",s/2);
}
}


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