POJ1279 Art Gallery
来源:互联网 发布:ping命令是哪个端口 编辑:程序博客网 时间:2024/06/08 12:48
这道题一定要好好纪念一下,改代码改了一整天。。。。
代码写出来后一直WA,原来以为是精度问题或者程序哪个地方出了点小错误,毕竟第一次写排序增量算法
然后一直在改,后来实在找不出了,去看了discuss,有人说把g++改成c++就过了
然后自己也试了一遍,就过了。。。。
后来搜了下g++和c++的区别,得知g++输出浮点数时最好用%f,要不然有时候会出错。
然后把输出改成了%f,用g++提交,过了。。。
#include<stdio.h>#include<math.h>#include<string.h>#include<algorithm>using namespace std;const double eps=1e-8;struct Point { double x,y; Point(){}; Point(double xx,double yy) { x=xx; y=yy; } double operator ^(const Point b) const { return x*b.y-y*b.x; } double operator *(const Point b) const { return x*b.x+y*b.y; }};struct Line { Point s,e; double angle;};int n,m,ln,order[1505],dq[1505],bot,top;Point p[1505];Line l[1505];double multi(Point p,Point a,Point b) {//点b在直线p-a的左边时值>0 return (a.x-p.x)*(b.y-p.y)-(a.y-p.y)*(b.x-p.x);}int dblcmp(double a) { if (fabs(a)<eps) return 0; return a>0?1:-1;}//按极角从小到大排序//对于相同角度的两个半平面(a1a2,b1b2),只需要保留被其他角度相同的半平面覆盖的那一个int cmp(int a,int b) { int d=dblcmp(l[a].angle-l[b].angle); if (!d) return dblcmp(multi(l[a].s,l[b].s,l[b].e))<0; return d<0;}int EqualPoint(Point a, Point b) {//两点相等 return dblcmp(a.x - b.x) == 0 && dblcmp(a.y - b.y) == 0;}void AddLine(Point s,Point e){ l[ln].s=s; l[ln].e=e; l[ln].angle=atan2(e.y-s.y,e.x-s.x); order[ln]=ln; ln++;}Point Intersect(Line l1,Line l2) { /*double s1,s2; s1=multi(a.s,a.e,b.s); s2=multi(a.s,a.e,b.e); return Point((a.s.x*s2+a.e.x*s1)/(s1+s2),(a.s.y*s2+a.e.y*s1)/(s1+s2));*/ double dot1, dot2; Point p; dot1 = multi(l2.s, l1.e, l1.s); dot2 = multi(l1.e, l2.e, l1.s); p.x = (l2.s.x * dot2 + l2.e.x * dot1) / (dot2 + dot1); p.y = (l2.s.y * dot2 + l2.e.y * dot1) / (dot2 + dot1); return p;}int Judge(Line l0,Line l1,Line l2) { Point p=Intersect(l1,l2); return dblcmp(multi(l0.s,l0.e,p))>0;//因为该题是顺时针给出的点,所以p在直线左边即<0时,top--}void HPI(){int i,j; sort(order,order+ln,cmp); for(i=1,j=0;i<n;i++) { if (dblcmp(l[order[i]].angle-l[order[j]].angle)>0) order[++j]=order[i]; ln=j+1; } dq[0]=order[0]; dq[1]=order[1]; bot=0,top=1; for( i=2;i<ln;i++) { while(bot<top && Judge(l[order[i]],l[dq[top-1]],l[dq[top]])) top--; while(bot<top && Judge(l[order[i]],l[dq[bot+1]],l[dq[bot]])) bot++; dq[++top]=order[i]; } //对最后加进去的点后进行处理 while(bot<top && Judge(l[dq[bot]],l[dq[top-1]],l[dq[top]])) top--; while(bot<top && Judge(l[dq[top]],l[dq[bot+1]],l[dq[bot]])) bot++; //printf("%d %d\n",bot,top);m=0; if (top<=bot+1) return;//不能构成封闭的多边形 //最终的核即各线段所在直线的交点 for( i=bot;i<top;i++) p[m++]=Intersect(l[dq[i]],l[dq[i+1]]); if (top>bot+1) p[m++]=Intersect(l[dq[bot]],l[dq[top]]);//即最终的线段大于2条,可形成环时 m=unique(p,p+m,EqualPoint)-p;}double xmul(Point p0,Point p1,Point p2){ return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);}int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif // ONLINE_JUDGE int T,i; scanf("%d",&T); while(T--) { scanf("%d",&n); ln=0; memset(dq,0,sizeof(dq)); memset(order,0,sizeof(order)); double s=0; for(i=0;i<n;i++) scanf("%lf%lf",&p[i].x,&p[i].y); /*for(inti=0;i<n;i++) s+=p[i]^p[(i+1)%n]; if (s>0){ for(int i=0;i<n/2;i++) swap(p[i],p[n-1-i]); }*/ p[n]=p[0]; for(i=0;i<n;i++) AddLine(p[i],p[i+1]); HPI(); s=0; for(i=0;i<m;i++) { s+=p[i]^p[(i+1)%m]; } if (fabs(s)<eps) s=0.0; printf("%.2lf\n",fabs(s/2.0)); } return 0;}
0 0
- POJ1279 Art Gallery
- POJ1279-Art Gallery
- POJ1279 Art Gallery
- POJ1279 Art Gallery
- [POJ1279]Art Gallery(半平面交)
- poj1279——Art Gallery//半平面交 求面积
- POJ1279 && LA2512 Art Gallery(求多边形的核)
- POJ1279/ZOJ1369 Art Gallery,POJ2451 Uyuw's Concert(半平面交求多边形的核)
- poj1279-Art Gallery 直线围成的区域的面积(半平面交模板题)
- POJ 1279 Art Gallery
- poj 1279 Art Gallery
- UVA 1304 Art Gallery
- uva10078The Art Gallery
- poj 1279 Art Gallery
- POJ 1279 Art Gallery
- POJ 1279 Art Gallery
- Narrow Art Gallery
- POJ 1279 Art Gallery
- 如何使用 WIZnet 开源硬件封装库
- 信号中断 与 慢系统调用
- 使用varargh.h来实现可变参数列表以及varargh.h实现
- zoj 1088题解--Josephus 问题,加速解决
- asp.net uploadify文件已上传到指定目录,但进度条却显示的是上传失败信息HTTP Error
- POJ1279 Art Gallery
- Android 查看Android源码版本
- JNDI学习<一>
- 使用boost filesystem递归遍历文件夹
- Java初学习 - 并发有关的小结
- UVA The Monocycle(BFS 4种状态)
- mapreduce_shuffle does not exist
- gsoap编译及使用例子
- sql语句中用问号代替参数