鏈接:http://poj.org/problem?id=1279

Art Gallery
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 5337   Accepted: 2277

Description

The art galleries of the new and very futuristic building of the Center for Balkan Cooperation have the form of polygons (not necessarily convex). When a big exhibition is organized, watching over all of the pictures is a big security concern. Your task is that for a given gallery to write a program which finds the surface of the area of the floor, from which each point on the walls of the gallery is visible. On the figure 1. a map of a gallery is given in some co-ordinate system. The area wanted is shaded on the figure 2. 

Input

The number of tasks T that your program have to solve will be on the first row of the input file. Input data for each task start with an integer N, 5 <= N <= 1500. Each of the next N rows of the input will contain the co-ordinates of a vertex of the polygon ? two integers that fit in 16-bit integer type, separated by a single space. Following the row with the co-ordinates of the last vertex for the task comes the line with the number of vertices for the next test and so on.

Output

For each test you must write on one line the required surface - a number with exactly two digits after the decimal point (the number should be rounded to the second digit after the decimal point).

Sample Input

1
7
0 0
4 4
4 7
9 7
13 -1
8 -6
4 -4

Sample Output

80.00

Source

 
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
这道题好坑的,题目根本没题给定的点有序,然后大家就一起照有序的来做了
自己写了个排序的,发现不行,如果默认有序,再去排序,就会得到错误的结
果,主要是极角排序,是根据角度,一点点逆时针移动,会使原多边形改变形
状,进而求出错误的结果。不知道有没有办法去解决这个问题
 
一下是错误排序代码:
 #include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm> #define eps 1e-8
#define MAXX 1510 typedef struct point
{
double x;
double y;
}point; point p[MAXX],s[MAXX]; using namespace std;
bool dy(double x,double y)
{
return x>y+eps;
}
bool xy(double x,double y)
{
return x<y-eps;
}
bool dyd(double x,double y)
{
return x>y-eps;
}
bool xyd(double x,double y)
{
return x<y+eps;
}
bool dd(double x,double y)
{
return fabs(x-y)<eps;
} double crossProduct(point a,point b,point c)
{
return (c.x-a.x)*(b.y-a.y)-(c.y-a.y)*(b.x-a.x);
} point IntersectPoint(point u1,point u2,point v1,point v2)
{
point ans=u1;
double t = ((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))/
((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));
ans.x += (u2.x-u1.x)*t;
ans.y += (u2.y-u1.y)*t;
return ans;
} double Area(point p[],int n)
{
double ans=0.0;
for(int i=; i<n-; i++)
{
ans += crossProduct(p[],p[i],p[i+]);
}
return fabs(ans)/2.0;
} double dist(point a,point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
} bool cmp(point a,point b)
{
double tmp=crossProduct(p[],a,b);
if(dd(tmp,0.0))
return dy(dist(p[],a),dist(p[],b));
return xy(tmp,0.0);
} point Getsort(int n)
{
int tmp=;
for(int i=; i<n; i++)
{
if(xy(p[i].x,p[tmp].x) || dd(p[i].x,p[tmp].x)&&xy(p[i].y,p[tmp].y))
{
tmp=i;
}
}// printf("%d^^",tmp);
swap(p[],p[tmp]);
sort(p+,p+n,cmp);
} void cut(point p[],point s[],int n,int &len)
{
point tp[MAXX];
p[n]=p[];
for(int i=; i<=n; i++)
{
tp[i]=p[i];
}
int cp=n,tc;
for(int i=; i<n; i++)
{
tc=;
for(int k=; k<cp; k++)
{
if(xyd(crossProduct(p[i],p[i+],tp[k]),0.0))
s[tc++]=tp[k];
if(xy(crossProduct(p[i],p[i+],tp[k])*
crossProduct(p[i],p[i+],tp[k+]),0.0))
s[tc++]=IntersectPoint(p[i],p[i+],tp[k],tp[k+]);
}
s[tc]=s[];
for(int k=; k<=tc; k++)
tp[k]=s[k];
cp=tc;
}
len=cp;
} int main()
{
int t,n,m,i,j;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i=; i<n; i++)
{
scanf("%lf%lf",&p[i].x,&p[i].y);
}
//point tmp=IntersectPoint(p[0],p[1],p[2],p[3]);
//printf("%lf %lf\n",tmp.x,tmp.y);
Getsort(n);//for(i=0; i<n; i++)printf("%lf**%lf*\n",p[i].x,p[i].y);
int len;
cut(p,s,n,len);//for(i=0; i<len; i++)printf("%lf==%lf=\n",s[i].x,s[i].y);
double area=Area(s,len);
printf("%.2lf\n",area);
}
return ;
}

利用面积正负来判断顺or逆,这种代码是以逆时针为主,我的面积顺时针为正,

需要改变方向

这是AC代码:
 #include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm> #define eps 1e-8
#define MAXX 1510 typedef struct point
{
double x;
double y;
}point; point p[MAXX],s[MAXX]; using namespace std;
bool dy(double x,double y)
{
return x>y+eps;
}
bool xy(double x,double y)
{
return x<y-eps;
}
bool dyd(double x,double y)
{
return x>y-eps;
}
bool xyd(double x,double y)
{
return x<y+eps;
}
bool dd(double x,double y)
{
return fabs(x-y)<eps;
} double crossProduct(point a,point b,point c)
{
return (c.x-a.x)*(b.y-a.y)-(c.y-a.y)*(b.x-a.x);
} point IntersectPoint(point u1,point u2,point v1,point v2)
{
point ans=u1;
double t = ((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))/
((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));
ans.x += (u2.x-u1.x)*t;
ans.y += (u2.y-u1.y)*t;
return ans;
} double Area(point p[],int n)
{
double ans=0.0;
p[n]=p[];
point tmp;
tmp.x=,tmp.y=;
for(int i=; i<n; i++)
{
ans += crossProduct(tmp,p[i],p[i+]);
}
return ans/2.0;
} void changeWise(point p[],int n)
{
for(int i=; i<n/; i++)
swap(p[i],p[n-i-]);
} double dist(point a,point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
/*
bool cmp(point a,point b)
{
double tmp=crossProduct(p[0],a,b);
if(dd(tmp,0.0))
return dy(dist(p[0],a),dist(p[0],b));
return xy(tmp,0.0);
} point Getsort(int n)
{
int tmp=0;
for(int i=1; i<n; i++)
{
if(xy(p[i].x,p[tmp].x) || dd(p[i].x,p[tmp].x)&&xy(p[i].y,p[tmp].y))
{
tmp=i;
}
}// printf("%d^^",tmp);
swap(p[0],p[tmp]);
sort(p+1,p+n,cmp);
}
*/
void cut(point p[],point s[],int n,int &len)
{
point tp[MAXX];
p[n]=p[];
for(int i=; i<=n; i++)
{
tp[i]=p[i];
}
int cp=n,tc;
for(int i=; i<n; i++)
{
tc=;
for(int k=; k<cp; k++)
{
if(xyd(crossProduct(p[i],p[i+],tp[k]),0.0))
s[tc++]=tp[k];
if(xy(crossProduct(p[i],p[i+],tp[k])*
crossProduct(p[i],p[i+],tp[k+]),0.0))
s[tc++]=IntersectPoint(p[i],p[i+],tp[k],tp[k+]);
}
s[tc]=s[];
for(int k=; k<=tc; k++)
tp[k]=s[k];
cp=tc;
}
len=cp;
} int main()
{
int t,n,m,i,j;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i=; i<n; i++)
{
scanf("%lf%lf",&p[i].x,&p[i].y);
}
double tmp=Area(p,n);
if(dy(tmp,0.0))
changeWise(p,n);
//point tmp=IntersectPoint(p[0],p[1],p[2],p[3]);
//printf("%lf %lf\n",tmp.x,tmp.y);
//Getsort(n);for(i=0; i<n; i++)printf("%lf**%lf*\n",p[i].x,p[i].y);
int len;
cut(p,s,n,len);//for(i=0; i<len; i++)printf("%lf==%lf=\n",s[i].x,s[i].y);
double area=Area(s,len);
printf("%.2lf\n",fabs(area));
}
return ;
}

poj 1279 -- Art Gallery (半平面交)的更多相关文章

  1. POJ 1279 Art Gallery 半平面交/多边形求核

    http://poj.org/problem?id=1279 顺时针给你一个多边形...求能看到所有点的面积...用半平面对所有边取交即可,模版题 这里的半平面交是O(n^2)的算法...比较逗比.. ...

  2. POJ 1279 Art Gallery 半平面交求多边形核

    第一道半平面交,只会写N^2. 将每条边化作一个不等式,ax+by+c>0,所以要固定顺序,方便求解. 半平面交其实就是对一系列的不等式组进行求解可行解. 如果某点在直线右侧,说明那个点在区域内 ...

  3. POJ 1279 Art Gallery(半平面交)

    题目链接 回忆了一下,半平面交,整理了一下模版. #include <cstdio> #include <cstring> #include <string> #i ...

  4. POJ 1279 Art Gallery 半平面交 多边形的核

    题意:求多边形的核的面积 套模板即可 #include <iostream> #include <cstdio> #include <cmath> #define ...

  5. poj 1279 Art Gallery - 求多边形核的面积

    /* poj 1279 Art Gallery - 求多边形核的面积 */ #include<stdio.h> #include<math.h> #include <al ...

  6. poj 1279 Art Gallery (Half Plane Intersection)

    1279 -- Art Gallery 还是半平面交的问题,要求求出多边形中可以观察到多边形所有边的位置区域的面积.其实就是把每一条边看作有向直线然后套用半平面交.这题在输入的时候应该用多边形的有向面 ...

  7. POJ 1279 Art Gallery(半平面交求多边形核的面积)

    题目链接 题意 : 求一个多边形的核的面积. 思路 : 半平面交求多边形的核,然后在求面积即可. #include <stdio.h> #include <string.h> ...

  8. [POJ]1279: Art Gallery

    题目大意:有一个N边形展馆,问展馆内有多少地方可以看到所有墙壁.(N<=1500) 思路:模板题,半平面交求出多边形的核后计算核的面积. #include<cstdio> #incl ...

  9. POJ 1279 Art Gallery【半平面交】(求多边形的核)(模板题)

    <题目链接> 题目大意: 按顺时针顺序给出一个N边形,求N边形的核的面积. (多边形的核:它是平面简单多边形的核是该多边形内部的一个点集该点集中任意一点与多边形边界上一点的连线都处于这个多 ...

随机推荐

  1. 小结 javascript中的类型检测

    先吐槽一下博客园的编辑器,太不好用了,一旦粘贴个表格进来就会卡死,每次都要用html编辑器写,不爽! 关于javascript的类型检测,早在实习的时候就应该总结,一直拖到现在,当时因为这个问题还出了 ...

  2. 批处理命令——echo 和 @

    [1]echo 命令简介 echo 命令的常见用法(必须掌握)分为以下几种情况: 一.无参数 作用:显示当前echo的状态:处于打开或关闭状态. 新建一个文本文件,命名为echo,修改类型为bat,用 ...

  3. 关于web开发前端h5框架的选择

    关于web开发前端h5框架的选择 看了很多移动版框架都是基于app混合式开发的,不是单独h5网站的基于h5开发的web框架从组件丰富度,兼容性,相关教程来说bootstrap还是最好的react和vu ...

  4. 我的Windows naked apps

    0. 驱动精灵全能网卡版 1. Microsoft Office 2010/2013 2. IE 11 3. Filezilla Client & Server 4. Google Chrom ...

  5. 使用percona xtradb cluster的IST方式添加新节点

    使用percona xtradb cluster的IST(Incremental State Transfer)特性添加新节点,防止新节点加入时使用SST(State SnapShop Transfe ...

  6. $q服务的API详解

    下面我们通过讲解$q的API让你更多的了解promise异步编程模式.$q是做为angularjs的一个服务而存在的,只是对promise异步编程模式的一个简化实现版,源码中剔除注释实现代码也就二百多 ...

  7. js笔记----(运动)分享 隐藏/显示

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  8. SlickGrid example 1: 最简单的例子和用法

    SlickGrid例子和用法 开始学习使用SlickGrid,确实挺好用,挺方便的. 官网地址: https://github.com/mleibman/SlickGrid 不多说,先上效果图. 上代 ...

  9. 20150629_Andriod_06_插入_删除_弹出式操作数据

    Fr_06_view_s6 --> activity_f6_insert              --> activity_f7__delete ******************** ...

  10. 多校3-Magician 分类: 比赛 2015-07-31 08:13 4人阅读 评论(0) 收藏

    Magician Time Limit: 18000/9000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total ...