UVA 10173

bitch bitch bitch...

TLE,WA一大坨,我是在拿生命来JUDGE啊。。

不得不说,UVA上的数据根本不是随机的,而是有预谋的。

for(int i=2;i<n;i++){
  while(stop>1&&cross(p[i],p[st[stop-1]],p[st[stop-2]])>=0) stop--;   //这个我本来是cross(p[i],p[st[stop-1]],p[st[stop-2]])>0
  st[stop++]=i;
}

因为没加上一个“=”号,就把边上所有共线的点都搞上了,之后,由于N太大,无可奈何的TLE、WA了。呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵吕森哥哥哥哥哥可可

算法如下:

  1. 计算全部四个多边形的端点, 称之为 xminP, xmaxP, yminP, ymaxP。
  2. 通过四个点构造 P 的四条切线。 他们确定了两个“卡壳”集合。
  3. 如果一条(或两条)线与一条边重合, 那么计算由四条线决定的矩形的面积, 并且保存为当前最小值。 否则将当前最小值定义为无穷大。
  4. 顺时针旋转线直到其中一条和多边形的一条边重合。
  5. 计算新矩形的面积, 并且和当前最小值比较。 如果小于当前最小值则更新, 并保存确定最小值的矩形信息。
  6. 重复步骤4和步骤5, 直到线旋转过的角度大于90度。
  7. 输出外接矩形的最小面积。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define min(x,y) ((x)<(y)?(x):(y))
using namespace std;

struct point
{
    double x,y;
}p[1005];

int ans[1005],st[1005],stop,cnt,n;

int DB (double d){
	if (fabs(d)<1e-8)
		return 0;
	return d>0?1:-1;
}
double cross (point a,point b,point c){
	return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y);
}
double dot(point a,point b,point c){
    return (a.x-c.x)*(b.x-c.x)+(a.y-c.y)*(b.y-c.y);
}
bool cmp(point A,point B){
	if(A.y<B.y) return true;
	else if(A.y==B.y){
		if(A.x<B.x)return true;
	}
	return false;
}

void forTU(){
	stop=cnt=0;
	st[stop++]=0; st[stop++]=1;
	for(int i=2;i<n;i++){
		while(stop>1&&cross(p[i],p[st[stop-1]],p[st[stop-2]])>=0) stop--;
		st[stop++]=i;
	}
	for(int i=0;i<stop;i++)
	ans[cnt++]=st[i];
	stop=0; st[stop++]=n-1; st[stop++]=n-2;
	for(int i=n-3;i>=0;i--){
		while(stop>1&&cross(p[i],p[st[stop-1]],p[st[stop-2]])>=0) stop--;
		st[stop++]=i;
	}
	for(int i=1;i<stop;i++){
		ans[cnt++]=st[i];
	}
}

double roating(){
	cnt--;
    if(n<3) return 0;
    int i,m=1,q=1,r;
    double anst=1e10,a,b,c;
    for(i=0;i<cnt;i++){
		while (DB(cross(p[ans[(i+1)]],p[ans[(m+1)]],p[ans[i]])-cross(p[ans[(i+1)]],p[ans[m]],p[ans[i]])) >0)
  		m=(m+1)%cnt;
        while (DB(dot(p[ans[(q+1)]],p[ans[(i+1)]],p[ans[i]])-dot(p[ans[q]],p[ans[(i+1)]],p[ans[i]])) >0)
        q=(q+1)%cnt;
        if (i==0)
		r=q;
        while(DB(dot(p[ans[(r+1)]],p[ans[(i+1)]],p[ans[i]])-dot(p[ans[r]],p[ans[(i+1)]],p[ans[i]])) <= 0)
        r=(r+1)%cnt;
        a=cross(p[ans[(i+1)]],p[ans[m]],p[ans[i]]);
        b=dot(p[ans[q]],p[ans[(i+1)]],p[ans[i]])-dot(p[ans[r]],p[ans[(i+1)]],p[ans[i]]);
        c=dot(p[ans[(i+1)]],p[ans[(i+1)]],p[ans[i]]);
        anst=min(anst,a*b/c);
    }
    return anst;
}

int main (){
    while (scanf("%d",&n) && n!=0) {
        for (int i=0;i<n;i++)
		scanf("%lf%lf",&p[i].x,&p[i].y);
		sort(p,p+n,cmp);
        forTU();
        printf("%.4lf\n",roating());
    }
    return 0;
}

  

UVA 10173,布布扣,bubuko.com

时间: 2024-07-31 14:30:59

UVA 10173的相关文章

【最小矩形面积覆盖:凸包+旋转卡壳】UVA 10173 Smallest Bounding Rectangle

[最小矩形面积覆盖:凸包+旋转卡壳]UVA 10173 Smallest Bounding Rectangle 题目链接:UVA 10173 Smallest Bounding Rectangle 题目大意 给你n个点,求能够覆盖所有点集的最小矩形面积. 笔者的第2道凸包题目,凸包 + 旋转卡壳,实现点集的最小矩形面积覆盖问题 ">=0"写成"<=0"坑了我一下午!QAQ 说一下思路 ①Graham's Scan法构建凸包,时间复杂度O(nlogn) ②

此坑待填 离散化思想和凸包 UVA - 10173 Smallest Bounding Rectangle

Smallest Bounding Rectangle Given the Cartesian coordinates of n(>0)2-dimensional points, write a program that computes the area of their smallest bounding rectangle (smallest rectangle containing all the given points). Input The input le may contain

hdu3982 直线切多边形

题意:有一块蛋糕,上面有一颗cherry.用刀子切n次,求切完之后有cherry的那部分的面积 My solution: 先做一个大矩形,使cake内切于这个大矩形.如图: 然后不断切这个大矩形,每次切割的时候保留与cherry同侧的那部分.最后剩下的就是一个多边形.求该多边形与圆的面积交即可. 在切割的时候如何保证留下来的是与cherry同侧的部分呢?很简单 方法不难,但是一直WA= =.遇到了个奇怪的问题: 对于这组数据: 3 5 2-5 0 5 3-5 0 5 -30 05 2-5 0 5

【转】[专题学习][计算几何]

原文地址:http://www.cnblogs.com/ch3656468/archive/2011/03/02/1969303.html 基本的叉积.点积和凸包等东西就不多说什么了,网上一搜一大堆,切一些题目基本熟悉了就差不多了. 一些基本的题目可以自己搜索,比如这个blog:http://blog.sina.com.cn/s/blog_49c5866c0100f3om.html 接下来,研究了半平面交,思想方法看07年朱泽园的国家队论文,模板代码参考自我校大牛韬哥: http://www.o

优质题表(机密版)

转载请注明出处:http://www.cnblogs.com/dashuzhilin/p/4556803.html 思维题: poj 1528 poj 1597 poj 2538 poj 2608 poj 2612 poj 2361 poj 2339 poj 2664 uva 10894 uva 10921   uva 10922   uva 10929 uva 10931   uva 10800   uva 10878 uva 10976   uva 10323   uva 201 poj 2

Rotating Scoreboard(半平面交模板题)

Rotating Scoreboard http://poj.org/problem?id=3335 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8506   Accepted: 3357 Description This year, ACM/ICPC World finals will be held in a hall in form of a simple polygon. The coaches and spe

UVA 562 Dividing coins --01背包的变形

01背包的变形. 先算出硬币面值的总和,然后此题变成求背包容量为V=sum/2时,能装的最多的硬币,然后将剩余的面值和它相减取一个绝对值就是最小的差值. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; #define N 50007 int c[102],d

UVA 10341 Solve It

Problem F Solve It Input: standard input Output: standard output Time Limit: 1 second Memory Limit: 32 MB Solve the equation: p*e-x + q*sin(x) + r*cos(x) + s*tan(x) + t*x2 + u = 0 where 0 <= x <= 1. Input Input consists of multiple test cases and te

UVA 11014 - Make a Crystal(容斥原理)

UVA 11014 - Make a Crystal 题目链接 题意:给定一个NxNxN的正方体,求出最多能选几个整数点.使得随意两点PQ不会使PQO共线. 思路:利用容斥原理,设f(k)为点(x, y, z)三点都为k的倍数的点的个数(要扣掉一个原点O).那么全部点就是f(1),之后要去除掉共线的,就是扣掉f(2), f(3), f(5)..f(n).n为素数.由于这些素数中包括了合数的情况,而且这些点必定与f(1)除去这些点以外的点共线,所以扣掉.可是扣掉后会扣掉一些反复的.比方f(6)在f