swustoj凸包面积(分治法)

原创 2018年04月17日 20:46:55

麦兜是个淘气的孩子。一天,他在玩钢笔的时候把墨水洒在了白色的墙上。再过一会,麦兜妈就要回来了,麦兜为了不让妈妈知道这件事情,就想用一个白色的凸多边形把墙上的墨点盖住。你能告诉麦兜最小需要面积多大的凸多边形才能把这些墨点盖住吗? 现在,给出了这些墨点的坐标,请帮助麦兜计算出覆盖这些墨点的最小凸多边形的面积。

输入

多组测试数据。第一行是一个整数T,表明一共有T组测试数据。
每组测试数据的第一行是一个正整数N(0< N < = 105),表明了墨点的数量。接下来的N行每行包含了两个整数Xi和Yi(0<=Xi,Yi<=2000),表示每个墨点的坐标。每行的坐标间可能包含多个空格。

输出

每行输出一组测试数据的结果,只需输出最小凸多边形的面积。面积是个实数,小数点后面保留一位即可,不需要多余的空格。

样例输入

2
4
0 0
1 0
0 1
1 1
2
0 0
0 1

样例输出

1.0
0.0

题解:分治法求解。

1,找出所有点中x值最小和最大的点就是凸包顶点。

2,以这两点为界将点划分为上包和下包。

3,求上包:每次找离直线最远的点,必是凸包顶点。下包一样求解。

3,递归求解上下包,顺便求面积。


#include<iostream>
#include<string.h>
#include<algorithm>
#include<cmath>
#include<map>
#include<string>
#include<stdio.h>
#include<vector>
#include<stack>
using namespace std;
struct node {
	int x, y;
}s[105];
vector<node>ans;
vector<int>::iterator it;
double ansans;
//求点s3在点s1,s2所连直线的上边,如果满足返回true
bool isup(node s1, node s2, node s3) {
	swap(s1, s2);
	int juge = s1.x*s2.y + s3.x*s1.y + s2.x*s3.y - s3.x*s2.y - s2.x*s1.y - s1.x*s3.y;
	//点s3在点s1,s2z左侧
	if ( juge > 0) {
		return 1;
	}
	else if(juge <= 0) {
		return 0;
	}
}
//求两点直线距离
double getlinedis(node s1, node s2) {
	return sqrt(pow(s1.x - s2.x, 2) + pow(s1.y - s2.y, 2));
}
//求三点决定的三角形面积
double getdis(node s1, node s2, node s3) {
	double a = getlinedis(s1, s2);
	double b = getlinedis(s1, s3);
	double c = getlinedis(s2, s3);
	double p = (a + b + c) / 2;
	return sqrt(p * (p - a)*(p - b)*(p - c));
}
//isupdp为1代表求上包,否则下包
void getup(node s1, node s2, vector<node>up,bool isupdp) {
	node temp;
	double _max = 0;
	double maxs = 0;
	for (int i = 0;i < up.size();i++) {
		double dis = getdis(s1, s2, up[i]);
		bool tt = isup(s1, s2, up[i]);
		if (!isupdp) {
			tt = !tt;
		}
		if (tt) {
			if (dis > _max) {
				_max = dis;
				maxs = dis;
				temp = up[i];
			}
		}
		else {
			if(up[i].x)
			up.erase(up.begin()+i);
			if (i != 0) {
				i--;
			}
		}
	}
	ans.push_back(temp);
	ansans += maxs;
	if (up.size() > 1) {
		getup(s1, temp, up,isupdp);
		getup(temp, s2, up, isupdp);
	}
}

bool cmp(node a, node b) {
	return a.y < b.y;
}

int main()
{
	int t;
	cin >> t;

	while (t--) {
		vector<node>v;
		int n;
		cin >> n;
		int _minid, _maxid;
		_minid = 0;
		_maxid = 0;
		for (int i = 0;i < n;i++) {
			scanf("%d%d", &s[i].x, &s[i].y);
			v.push_back(s[i]);
			if (s[_maxid].x > s[i].x) {
				_maxid = i;
			}
			if (s[_minid].x < s[i].x) {
				_minid = i;
			}
		}
		vector<node>up, down;
		for (int i = 0;i < n;i++) {
			if (i != _minid && i != _maxid) {
				if (isup(s[_minid], s[_maxid], s[i])) {
					up.push_back(s[i]);
				}
				else {
					down.push_back(s[i]);
				}
			}
		}
		ans.push_back(s[_minid]);
		ans.push_back(s[_maxid]);
		getup(s[_minid], s[_maxid], up, 1);
		getup(s[_minid], s[_maxid], down, 0);
		sort(ans.begin(), ans.end(), cmp);
		printf("%.1lf\n", ansans);
		ansans = 0;
	}
	return 0;
}



版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Swust_Zeng_zhuo_K/article/details/79980454

swust oj凸包面积(0249)_分治法

本文目录:oj题目 -> 分治法思路 -> 具体过程 -> tips -> 测试数据 -> 代码 这道题本身不是很难哟,不要被吓到,然后就可以开始做了O(∩_∩)O~~ 题目: 分治法...
  • qq_33810513
  • qq_33810513
  • 2016-05-18 00:07:04
  • 642

算法:分治法求凸包上的点以及由凸包所构成的多边形的面积

在平面上有若干个点,编写程序求其凸包上的点以及由凸包所构成的多边形的面积。 输入要求:输入的第一行是一个整数n,表示点的个数。其后的n行,每行有两个整数,中间空格隔开,分别表示点的X,Y坐标。 输...
  • Eric_KEY
  • Eric_KEY
  • 2016-11-13 17:44:40
  • 1027

凸包算法(二)--凸包面积

 凸包面积算法1.选取p0作为y坐标最小的点,如果y坐标相等,选取x坐标最小的点2.对剩余的点相对与p0点的极角进行排序(比较叉积 )3.去除极角相等的点,即距离最远的点4.初始化堆栈5.折线段拐向判...
  • liufei_learning
  • liufei_learning
  • 2010-10-20 23:44:00
  • 6187

凸包问题之分治法

凸包:按横坐标排序,以最小点与最大点之间的连线为准,在直线一侧找使三角形面积最大的点,此点必在凸包内,以找到点与最大点或最小点继续递归以寻找最大三角形面积寻找凸包点,直至找不到符合条件的点。 实现代...
  • d2457638978
  • d2457638978
  • 2015-12-07 00:11:17
  • 3053

swustoj----249凸包的面积(分治法)

本题使用分治法解决 题目链接:http://acm.swust.edu.cn/problem/0249/ 先导知识: 知道三点求三角形面积公式   设A(x1,...
  • SpringRain_s
  • SpringRain_s
  • 2017-04-13 12:25:59
  • 197

利用分治法解决凸包问题

凸包的意思就是包含所有给定点的凸多边形。 ![这里写图片描述](http://img.blog.csdn.net/20170530091726010?watermark/2/text/aHR0cDov...
  • sinat_36246371
  • sinat_36246371
  • 2017-05-30 09:44:46
  • 1328

分治法解决凸包问题(C语言实现)

  • 2014年05月28日 19:39
  • 1KB
  • 下载

分治法解决凸包问题

分治法就是吧一个大问题分成几个结构相同的子问题,再把子问题分解成更小的子问题.......      分治法解决凸包问题的大体思路就是,取横坐标最小的点p0和横坐标最大pn的点(这两个点一点在凸包上,...
  • zbspy_ZJF
  • zbspy_ZJF
  • 2017-12-15 18:07:46
  • 280

学习凸包(二):分治法求解

接上文:学习凸包(一):暴力算法求解http://128kj.iteye.com/blog/1748442 Java代码 import ...
  • shenzhenhair
  • shenzhenhair
  • 2013-02-22 19:56:21
  • 445

分治法求解凸包问题

  • 2015年04月13日 21:04
  • 4KB
  • 下载
收藏助手
不良信息举报
您举报文章:swustoj凸包面积(分治法)
举报原因:
原因补充:

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