| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
Re:第二个数据就挂了,找了一份凸包和一份求多边形面积,结果居然也挂了In Reply To:是这样…… Posted by:frkstyc at 2007-08-24 00:02:31 第二个数据是
10
-521 -296
-575 -419
-516 -864
-114 -106
187 295
-404 12
840 -852
948 -405
247 704
1 170
28638
#include<cstdio>
#include<algorithm>
using namespace std;
#define MAX 10000
typedef struct
{
int x,y;
}POINT;
POINT tree[MAX];
int n,sel_num;
int doudis(POINT end,POINT from)
{
return (end.x-from.x)*(end.x-from.x)+(end.y-from.y)*(end.y-from.y);
}
int crossmul(POINT fir,POINT sec,POINT mid)
{
return (fir.x-mid.x)*(sec.y-mid.y)-(fir.y-mid.y)*(sec.x-mid.x);
}
bool cmp(const POINT fir,const POINT sec)
{
if(crossmul(fir,sec,tree[0])>0)
return true;
return crossmul(fir,sec,tree[0])==0&&doudis(fir,tree[0])<doudis(sec,tree[0]);
}
int mul(POINT fir,POINT sec,POINT thi)
{
return (fir.x-sec.x)*(sec.y-thi.y)-(fir.y-sec.y)*(sec.x-thi.x);
}
void Graham()
{
int i,j;
int pt=0;
for(i=1;i<n;i++)
if(tree[i].y<tree[pt].y||(tree[i].y==tree[pt].y&&tree[i].x<tree[pt].x))
pt=i;
swap(tree[0],tree[pt]);
sort(tree+1,tree+n,cmp);
sel_num=3;
for(i=3;i<n;i++)
{
while(mul(tree[i],tree[sel_num-1],tree[sel_num-2])>=0)
sel_num--;
tree[sel_num++]=tree[i];
}
}
//int area2()
//{
// int i,s;
// s=tree[0].y*(tree[sel_num-1].x-tree[1].x);
// for(i=1;i<sel_num;i++)
// s+=tree[i].y*(tree[i-1].x-tree[(i+1)%sel_num].x);
// return s>0?s:-s;
//}
//int area2()
//{
// int i,s;
// s=tree[0].x*tree[sel_num-1].y-tree[0].y*tree[sel_num-1].x;
// for(i=1;i<sel_num;i++)
// s+=tree[i-1].x*tree[i].y-tree[i-1].y*tree[i].x;
// return s>0?s:-s;
//}
int area2()
{
int i,s;
s=0;
tree[sel_num]=tree[0];
for(i=0;i<sel_num;i++)
{
s+=tree[i].x*tree[i+1].y-tree[i].y*tree[i+1].x;
// printf("%d\n",s);
}
return s>0?s:-s;
}
int main()
{
int i;
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d%d",&tree[i].x,&tree[i].y);
Graham();
// printf("%d\n",sel_num);
// for(i=0;i<sel_num;i++)
// printf("%d %d\n",tree[i].x,tree[i].y);
printf("%d\n",area2()/100);
// while(1);
return 0;
}
网上的东西
#include<iostream.h>
#include<math.h>
#define MAX 1000
int main()
{
int n,i;
double point[MAX][2],area;
while(cin>>n&&n>=3){
for(i=0;i<n;i++) cin>>point[i][0]>>point[i][1]; //沿着多边形的边逐个输入各顶点坐标;
area=0;
for(i=0;i<n;i++){
int next=(i+1)>=n?0:(i+1);
area+=(point[next][0]-point[i][0])*(point[next][1]+point[i][1])/2; //使用向量法求解!!!
}
area=fabs(area); //注意!!!
cout<<"area="<<area/50<<endl;
}
return 0;
}
/**********************************************
寻找凸包的graham 扫描法
PointSet为输入的点集;
ch为输出的凸包上的点集,按照逆时针方向排列;
n为PointSet中的点的数目
len为输出的凸包上的点的个数
**********************************************/
#include<stdio.h>
#include<math.h>
const double INF=1E200;
const double EP=1E-10;
#define PI acos(-1)
/*基本几何数据结构*/
//点(x,y)
struct POINT
{
double x;
double y;
};
// 返回两点之间欧氏距离
double distance(POINT p1, POINT p2)
{
return sqrt( (p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
}
/******************************************************************************
r=multiply(sp,ep,op),得到(sp-op)*(ep-op)的叉积
r>0:ep在矢量opsp的逆时针方向;
r=0:opspep三点共线;
r<0:ep在矢量opsp的顺时针方向
*******************************************************************************/
//叉积就是2向量形成的平行四边形的面积
double multiply(POINT sp,POINT ep,POINT op)
{
return((sp.x-op.x)*(ep.y-op.y)-(ep.x-op.x)*(sp.y-op.y));
}
int partition(POINT a[],int p,int r)
{
int i=p,j=r+1,k;
double ang,dis;
POINT R,S;
k=(p+r)/2;//防止快排退化
R=a[p];
a[p]=a[k];
a[k]=R;
R=a[p];
dis=distance(R,a[0]);
while(1)
{
while(1)
{
++i;
if(i>r)
{
i=r;
break;
}
ang=multiply(R,a[i],a[0]);
if(ang>0)
break;
else if(ang==0)
{
if(distance(a[i],a[0])>dis)
break;
}
}
while(1)
{
--j;
if(j<p)
{
j=p;
break;
}
ang=multiply(R,a[j],a[0]);
if(ang<0)
break;
else if(ang==0)
{
if(distance(a[j],a[0])<dis)
break;
}
}
if(i>=j)break;
S=a[i];
a[i]=a[j];
a[j]=S;
}
a[p]=a[j];
a[j]=R;
return j;
}
void anglesort(POINT a[],int p,int r)
{
if(p<r)
{
int q=partition(a,p,r);
anglesort(a,p,q-1);
anglesort(a,q+1,r);
}
}
void Graham_scan(POINT PointSet[],POINT ch[],int n,int &len)
{
int i,k=0,top=2;
POINT tmp;
// 选取PointSet中y坐标最小的点PointSet[k],如果这样的点有多个,则取最左边的一个
for(i=1;i<n;i++)
if ( PointSet[i].y<PointSet[k].y ||
(PointSet[i].y==PointSet[k].y) && (PointSet[i].x<PointSet[k].x) )
k=i;
tmp=PointSet[0];
PointSet[0]=PointSet[k];
PointSet[k]=tmp; // 现在PointSet中y坐标最小的点在PointSet[0]
/* 对顶点按照相对PointSet[0]的极角从小到大进行排序,极角相同
的按照距离PointSet[0]从近到远进行排序 */
anglesort(PointSet,1,n-1);
ch[0]=PointSet[0];
ch[1]=PointSet[1];
ch[2]=PointSet[2];
for (i=3;i<n;i++)
{
while (multiply(PointSet[i],ch[top],ch[top-1])>=0) top--;
ch[++top]=PointSet[i];
}
len=top+1;
}
#define M 100000
POINT a[M],b[M];
int main()
{
int n,i,l;
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%lf %lf",&a[i].x,&a[i].y);
Graham_scan(a,b,n,l);
for(i=0;i<l;i++)
printf("%lf %lf\n",b[i].x,b[i].y);
while(1);
return 0;
}
Followed by:
Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator