UVa 1304 - Art Gallery

原创 2015年11月17日 23:41:21

计算几何是个有些许麻烦的专题 , 因为即使是算法对了 , 精度问题也是不可忽视的 , 调试会有些麻烦......


提示: 

1. 是一个有点裸的半平面交的题目 , 不需要用O(nlogn)复杂度的算法

2. 你可以先写写白书上的一个CurPolygon的函数(在半平面交的最开始处)


如果你完全那样写估计就会得到WA , 我就是这么干的 , 但并不要紧 , 因为你可能和我一样就只有一个地方有问题

强烈建议先自己尝试调错(想想我刚开始的抱怨), 下面我给出代码 , 在代码后我会解释精度问题的原因(其实书上提笔带过):


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <deque>
#include <stack>
#include <algorithm>

using namespace std;
double eps = 1e-10;
int dcmp(double a){ return fabs(a)<eps?0:(a<0?-1:1); }

struct points
{
	double x , y;
	void read(){ cin>>x>>y; }
	points(double x = 0 , double y = 0):x(x),y(y){}
	bool operator <(const points& b)const { return dcmp(x-b.x)<0 || (dcmp(x-b.x)==0 && dcmp(y-b.y)<0); }
};

typedef points Vector;
typedef vector<points> Polygon;

Vector operator -(Vector a , Vector b) { return Vector(a.x-b.x , a.y-b.y); }
Vector operator +(Vector a , Vector b) { return Vector(a.x+b.x , a.y+b.y); }
Vector operator *(Vector a , double b) { return Vector(a.x*b   , a.y*b  ); }
Vector operator /(Vector a , double b) { return Vector(a.x/b   , a.y/b  ); }
bool operator ==(Vector a , Vector b) { return dcmp(a.x-b.x)==0 && dcmp(a.y-b.y)==0; }
bool operator !=(Vector a , Vector b) { return dcmp(a.x-b.x) || dcmp(a.y-b.y); }
double Dot(Vector a , Vector b) { return a.x*b.x+a.y*b.y; }
double Cross(Vector a , Vector b) { return a.x*b.y-a.y*b.x; }
double Length(Vector a) { return sqrt(Dot(a, a)); }
double angle(Vector a){ return atan2(a.y, a.x); }
double angle(Vector a , Vector b) { return acos(Dot(a, b)/Length(a)/Length(b)); }

Polygon p , ne;
points a[2000];

points LinesIntersection(points p , Vector v , points q , Vector w)
{
	Vector u = p-q;
	double t = Cross(w, u)/Cross(v, w);
	return p+v*t;
}

bool OnSegment(points p , points a , points b)
{
	return dcmp(Dot(a-p, b-p))<0;
}

Polygon CutAPolygon(points a , points b , Polygon p)
{
	int n = (int)p.size();
	ne.clear();
	for(int i=0;i<p.size();i++)
	{
		points c = p[i];
		points d = p[(i+1)%n];
		if(dcmp(Cross(b-a, c-a))>=0) ne.push_back(c);
		if(dcmp(Cross(b-a, c-d)))
		{
			points e = LinesIntersection(a, b-a, c, d-c);
			if(OnSegment(e, c, d)) ne.push_back(e);
		}
	}
	return ne;
}

double PolygonArea(Polygon p)
{
	double res = 0;
	int n = (int)p.size();
	for(int i=1;i<n-1;i++) res+= Cross(p[i]-p[0], p[(i+1)]-p[0]);
	return res/2.0;
}

int main(int argc, char *argv[]) {
	
	int t , n;
	cin>>t;
	while(t-- && cin>>n)
	{
		for(int i=0;i<n;i++)
			a[i].read();
		for(int i=0;i<n;i++) p.push_back(a[i]);
		if(PolygonArea(p)<0) 
		{
			reverse(a, a+n);
			reverse(p.begin(), p.end()); 
		}
		for(int i=0;i<n;i++)	
			p = CutAPolygon(a[i], a[(i+1)%n], p);

		printf("%.2lf\n",fabs(PolygonArea(p)));
	}
	
	return 0;
}


正如你所见的 , 我的OnSegment是一个不正确的函数 , 丢失了对正弦值的约束(其实在这个题目中是不用约束的) , 然而如果加上那个约束就会导致精度问题 , 由于精度不够 , 所以这个值很难是零(博主曾在调错中出现过这个值是4的情况) , 那你可能奇怪 , 为什么其他的(例如Dot)约束为什么不回引起精度问题呢 , 原因很简单 , 0是最难判断的 , 可以说0是一个绝对的量 , 但是正数和负数都是允许有一定的精度误差的


PS: 貌似博主的正确程序被弄掉了 , 这个程序不一定是正确的 , 但是稍稍修改初始化半平面的代码就可以了 , (也就是初始的那个平面不用题目给的多边形,而是自己加一个很大的矩形) , 或者联系我讨论: QQ 812483101

版权声明:大家可以随意转载 , 能帮助到更多的人博主十分开心:-)

UVa在线比赛单题汇总-----DP专题

动态规划基础 例题 LA 3882 UVa 3882 - And Then There Was One 递推------------无力orz UVa 10635 10635 -...
  • cyendra
  • cyendra
  • 2013年04月21日 21:29
  • 2256

UVA 156 Ananagrams 模拟+字符串处理

题意:把每个单词全部转化成小写字母,对每个单词,看它的字母重排后得到的单词在所有输入的单词中是否出现过,若没有出现,就输出原单词。所有要输出的单词按字典序排列输出。 这题的模拟没有那么裸,要求挺多的...
  • hcbbt
  • hcbbt
  • 2013年08月24日 00:23
  • 2328

[刷题]算法竞赛入门经典 3-10/UVa1587 3-11/UVa1588

题目:算法竞赛入门经典 3-10/UVa1587:Box 代码://UVa1587 - Box #include unsigned rect[6];//每个面各有一个一样的对应面,故12个边只要定义...
  • XieNaoban
  • XieNaoban
  • 2016年07月20日 14:25
  • 1661

UVA 10078 The Art Gallery【输入点是否全部在凸包上】

题目大意:抽离模型为判定输入点是否全部在凸包上,是输出“No”,否输出“Yes”。 解题策略:求出凸包,直接判定“栈”中顶点数top与nodeNum的关系即可(一开始以为要用到判定点是否在多边形内这...
  • J_Dark
  • J_Dark
  • 2013年05月06日 16:47
  • 629

UVA 10078 The Art Gallery(凸多边形判定)

UVA 10078 The Art Gallery(凸多边形判定) http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemi...
  • u013480600
  • u013480600
  • 2014年10月15日 21:35
  • 971

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

/* poj 1279 Art Gallery - 求多边形核的面积 */ #include #include #include using namespace std; const do...
  • qq172108805
  • qq172108805
  • 2013年08月09日 19:07
  • 932

poj1279——Art Gallery//半平面交 求面积

用上题模板,一次AC。#include #include #include using namespace std; const int maxn=20010; const int boun...
  • k1246195917
  • k1246195917
  • 2011年05月19日 14:01
  • 510

POJ 1279 Art Gallery(半平面交求多边形核)

转载请注明出处,谢谢http://blog.csdn.net/acm_cxlove/article/details/7854526       by---cxlove 题目:求多边形核的面积。 ...
  • ACM_cxlove
  • ACM_cxlove
  • 2012年08月19日 11:36
  • 2503

POJ 1279 Art Gallery (半平面交求内核面积)

Art Gallery Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7508   Accepted: 2996...
  • qq_34374664
  • qq_34374664
  • 2017年04月14日 21:34
  • 200

poj1279-Art Gallery 直线围成的区域的面积(半平面交模板题)

Art Gallery Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7997   Accepted: 3182...
  • wang_heng199
  • wang_heng199
  • 2017年07月03日 10:13
  • 111
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:UVa 1304 - Art Gallery
举报原因:
原因补充:

(最多只允许输入30个字)