poj 3301 (三分) - xgtao -

题目链接

给出平面上一些点(坐标),让我们在平面上选择一个正方形能够覆盖这些所有的点,求这个正方形的最小面积。

我们很容易找到一个符合要求的正方形,也就是所有边都平行于坐标轴的正方形,那么我们就只找平行于坐标轴的正方形,我们将每个点都旋转一定的角度,他们的相对位置不变,而正方形却相对于点在旋转,面积在改变,那么就可以找到最小的正方形.

我们只需要考虑最优的旋转角度.

假设旋转的角度为f,初始点的坐标为(x,y)与x轴的夹角为a,距离坐标原点的长度为len,那么x = cos(a)*len,y = sin(a)*len,nx = cos(a+f)*len,ny = sin(a+f)*len

拆开nx = cos(a)*cos(f)*len-sin(a)*sin(f)*len,ny = sin(a)*cos(f)*len+cos(a)*sin(f)*len

也就是说 nx = cos(f)*x-sin(f)*y,ny = sin(f)*x+cos(f)*y;

正方形的边长等于max(rightx-leftx,upy-downy) = max(cos(f)*(x1-x2)-sin(f)*(y1-y2),sin(f)*(x1-x2)+cos(f)*(y1-y2))(x1>x2 &&  y1>y2)

等于 max(sqrt((x1-x2)^2+(y1-y2)^2)sin(f+p1),sqrt((x1-x2)^2+(y1-y2)^2)sin(f+p2))

那么边长是由K*sin(f+p)转化而来的,那么在这个函数上一定存在一个角度使得边长最小,还有一个很显然的就是旋转角度在180°之内根据对称一定会找到最优解,那么f+p就在(-0.5*pi,pi)之间那么就是一个单峰函数,那么就可以三分角度了。

不知道为什么交G++就WA了,交C++就A了。。。

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
const double pi = acos(-1.0);
const double eps = 1e-8;
const int maxn = 510;
const double inf = 0xfffffff;
struct node{
	double x,y;
}p[maxn];
int n,T;
node rotate(node p,double k){
	node a;
	a.x = p.x*cos(k)-p.y*sin(k);
	a.y = p.x*sin(k)+p.y*cos(k);
	return a;
}

double calc(double k){
	double minx = inf,miny = inf;
	double maxx = -inf,maxy = -inf;
	for(int i = 1;i <= n;++i){
		node np;
		np = rotate(p[i],k);
		minx = min(minx,np.x),miny = min(miny,np.y);
		maxx = max(maxx,np.x),maxy = max(maxy,np.y);
	}
	return max(maxx-minx,maxy-miny);
}

int main(){
	scanf("%d",&T);
	while(T--){
		scanf("%d",&n);
		memset(p,0,sizeof(p));
		for(int i = 1;i <= n;++i){
			scanf("%lf%lf",&p[i].x,&p[i].y);
		}
		double l = 0.0,r = pi,mid,rmid;
		while (l + eps < r) {
			mid = (l+r)/2;
			rmid = (mid+r)/2;
			if(calc(mid) < calc(rmid)) r = rmid;
			else l = mid;
		}
		double len = calc(l);
		printf("%.2lf\n",len*len);
	}
	return 0;
}

  

时间: 2024-10-25 09:20:37

poj 3301 (三分) - xgtao -的相关文章

POJ 3301 Texas Trip (三分)

题目链接 题意 : 给你若干个点,让你找最小的正方形覆盖这所有的点.输出面积. 思路 : 三分枚举正方形两对边的距离,然后求出最大,本题用的是旋转正方形,也可以用旋转点,即点的相对位置不变. 正方形从0度到180度变化的过程中,把所有点覆盖,面积肯定是有一个最小峰值,是一个凸函数.因此可以用三分法解决.这里有一个难点就是已知两个定点的x,y坐标,过这两个点做两条平行线,平行线并与x轴成d度的角,怎么算出两条平行线的距离. d1 = fabs(cos(d)*(yi-yj)-sin(d)*(xi-x

POJ 3301:Texas Trip(计算几何+三分)

http://poj.org/problem?id=3301 题意:在二维平面上有n个点,每个点有一个坐标,问需要的正方形最小面积是多少可以覆盖所有的点. 思路:从第二个样例可以看出,将正方形旋转45°的时候,面积是最小的. 因此考虑旋转正方形,就可以当作旋转本来的点,对于旋转后的点,求最大的x和最小的x,最大的y和最小的y,就可以求得覆盖旋转后的点的正方形面积了. 然后对于每一个角度,都要进行判断,这个时候就觉得要用到X分了. 因为不满足单调性,所以用了三分.(其实也不太清楚为什么能三分).

三分 --- POJ 3301 Texas Trip

Texas Trip Problem's Link:   http://poj.org/problem?id=3301 Mean: 给定n(n <= 30)个点,求出包含这些点的面积最小的正方形的面积. analyse: 首先要确定的是旋转的角度在0到180度之间即可,超过180度是和前面的相同的. 坐标轴旋转后,坐标变换为: X’ = x * cosa - y * sina; y’ = y * cosa + x * sina; Time complexity: O(n) Source code

poj 3301 Texas Trip(几何+三分)

Description After a day trip with his friend Dick, Harry noticed a strange pattern of tiny holes in the door of his SUV. The local American Tire store sells fiberglass patching material only in square sheets. What is the smallest patch that Harry nee

POJ 3301 Texas Trip

题目链接:http://poj.org/problem?id=3301 Texas Trip Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4935 Accepted: 1543 Description After a day trip with his friend Dick, Harry noticed a strange pattern of tiny holes in the door of his SUV. The

POJ 3737/三分

题目链接[http://poj.org/problem?id=3737] 题意:给出一个圆锥的表面积,求最大的体积,并输出最大体积的时候的圆锥的高度和底面积. 方法一: 根据定理:圆锥的表面积一定的时候,当圆锥的斜边长度是底边半径三倍的时候,圆锥的体积最大. #include<cmath> #include<cstdio> const double PI = acos(-1.0); int main () { double s,h,r,v; while(~scanf("%

POJ 3301

开始就是瞄着三分来做的,但看题目,感觉是旋转卡壳吧..可是,用了旋转卡壳还三分条毛啊.. 可以令正方形不旋转,而改为令点绕原点旋转,这样,很好的解决了问题,就可以比较X轴最大长度和Y轴最大长度来确定正方形的边长了.然后三分旋转角度就可以了. #include <iostream> #include <cmath> #include <cstdio> #include <algorithm> using namespace std; struct Point{

三分算法

三分算法 二分算法解决的是具有单调性的问题. 三分算法解决的是抛物线的类型,上凸,下凹. mid=(Left+Right)/2; midmid=(Right+mid)/2; 题目类型有: HDU :3400  2298  4454  2438  3756 POJ:  3301   3737 ZOJ: 3203

三分查找

我们都知道 二分查找 适用于单调函数中逼近求解某点的值. 如果遇到凸性或凹形函数时,可以用三分查找求那个凸点或凹点. 下面的方法应该是三分查找的一个变形. 如图所示,已知左右端点L.R,要求找到白点的位置. 思路:通过不断缩小 [L,R] 的范围,无限逼近白点. 做法:先取 [L,R] 的中点 mid,再取 [mid,R] 的中点 mmid,通过比较 f(mid) 与 f(mmid) 的大小来缩小范围. 当最后 L=R-1 时,再比较下这两个点的值,我们就找到了答案. 1.当 f(mid) >