2015年百度之星初赛(1) --- F 矩形面积
矩形面积
每组测试数据占若干行,第一行一个正整数 $N(1 \leq N < \leq 1000)$,代表矩形的数量。接下来 N 行,每行 8 个整数$x_1, y_1, x_2, y_2, x_3, y_3, x_4, y_4$,代表矩形的四个点坐标,坐标绝对值不会超过10000。
第一行输出"Case #i:",i 代表第 i 组测试数据。
第二行包含1 个数字,代表面积最小的矩形的面积,结果保留到整数位。
Problem's Link: http://acm.hdu.edu.cn/showproblem.php?pid=5251
Mean:
略
analyse:
把n个矩形的点输入多边形寻找最小覆盖面积矩形的模版代码中就OK,网上套的模板。
Time complexity: O(n)
Source code:
/*
* this code is made by crazyacking
* Verdict: Accepted
* Submission Date: 2015-05-31-23.18
* Time: 0MS
* Memory: 137KB
*/
#include <queue>
#include <cstdio>
#include <set>
#include <string>
#include <stack>
#include <cmath>
#include <climits>
#include <map>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#define LL long long
#define ULL unsigned long long
using namespace std;
const double eps = 1e-;
const int N = ;
int sign(double d)
{
return d < -eps ? - : (d > eps);
}
struct point
{
double x, y;
point operator-(point d){
point dd;
dd.x = this->x - d.x;
dd.y = this->y - d.y;
return dd;
}
point operator+(point d){
point dd;
dd.x = this->x + d.x;
dd.y = this->y + d.y;
return dd;
}
void read(){ scanf("%lf%lf", &x, &y); }
}ps[N]; int n, cn; double dist(point d1, point d2)
{
return sqrt(pow(d1.x - d2.x, 2.0) + pow(d1.y - d2.y, 2.0));
} double dist2(point d1, point d2)
{
return pow(d1.x - d2.x, 2.0) + pow(d1.y - d2.y, 2.0);
} bool cmp(point d1, point d2)
{
return d1.y < d2.y || (d1.y == d2.y && d1.x < d2.x);
} //st1-->ed1叉乘st2-->ed2的值
double xmul(point st1, point ed1, point st2, point ed2)
{
return (ed1.x - st1.x) * (ed2.y - st2.y) - (ed1.y - st1.y) * (ed2.x - st2.x);
} double dmul(point st1, point ed1, point st2, point ed2)
{
return (ed1.x - st1.x) * (ed2.x - st2.x) + (ed1.y - st1.y) * (ed2.y - st2.y);
} //多边形类
struct poly
{
static const int N = ; //点数的最大值
point ps[N+]; //逆时针存储多边形的点,[0,pn-1]存储点
int pn; //点数
poly() { pn = ; }
//加进一个点
void push(point tp)
{
ps[pn++] = tp;
}
//第k个位置
int trim(int k)
{
return (k+pn)%pn;
}
void clear(){ pn = ; }
}; //返回含有n个点的点集ps的凸包
poly graham(point* ps, int n)
{
std::sort(ps, ps + n, cmp);
poly ans;
if(n <= ){
for(int i = ; i < n; i++)
{
ans.push(ps[i]);
}
return ans;
}
ans.push(ps[]);
ans.push(ps[]);
point* tps = ans.ps;
int top = -;
tps[++top] = ps[];
tps[++top] = ps[];
for(int i = ; i < n; i++)
{
while(top > && xmul(tps[top - ], tps[top], tps[top - ], ps[i]) <= ) top--;
tps[++top] = ps[i];
} int tmp = top; //注意要赋值给tmp! for(int i = n - ; i >= ; i--)
{
while(top > tmp && xmul(tps[top - ], tps[top], tps[top - ], ps[i]) <= ) top--;
tps[++top] = ps[i];
}
ans.pn = top;
return ans;
}
//求点p到st->ed的垂足,列参数方程
point getRoot(point p, point st, point ed)
{
point ans;
double u=((ed.x-st.x)*(ed.x-st.x)+(ed.y-st.y)*(ed.y-st.y));
u = ((ed.x-st.x)*(ed.x-p.x)+(ed.y-st.y)*(ed.y-p.y))/u;
ans.x = u*st.x+(-u)*ed.x;
ans.y = u*st.y+(-u)*ed.y;
return ans;
} //next为直线(st,ed)上的点,返回next沿(st,ed)右手垂直方向延伸l之后的点
point change(point st, point ed, point next, double l)
{
point dd;
dd.x = -(ed - st).y;
dd.y = (ed - st).x;
double len = sqrt(dd.x * dd.x + dd.y * dd.y);
dd.x /= len, dd.y /= len;
dd.x *= l, dd.y *= l;
dd = dd + next;
return dd;
} //求含n个点的点集ps的最小面积矩形,并把结果放在ds(ds为一个长度是4的数组即可,ds中的点是逆时针的)中,并返回这个最小面积。
double getMinAreaRect(point* ps, int n, point* ds)
{
int cn, i;
double ans;
point* con;
poly tpoly = graham(ps, n);
con = tpoly.ps;
cn = tpoly.pn;
if(cn <= )
{
ds[] = con[]; ds[] = con[];
ds[] = con[]; ds[] = con[];
ans=;
}
else
{
int l, r, u;
double tmp, len;
con[cn] = con[];
ans = 1e40;
l = i = ;
while(dmul(con[i], con[i+], con[i], con[l])
>= dmul(con[i], con[i+], con[i], con[(l-+cn)%cn]))
{
l = (l-+cn)%cn;
}
for(r=u=i = ; i < cn; i++){
while(xmul(con[i], con[i+], con[i], con[u])
<= xmul(con[i], con[i+], con[i], con[(u+)%cn]))
{
u = (u+)%cn;
}
while(dmul(con[i], con[i+], con[i], con[r])
<= dmul(con[i], con[i+], con[i], con[(r+)%cn]))
{
r = (r+)%cn;
}
while(dmul(con[i], con[i+], con[i], con[l])
>= dmul(con[i], con[i+], con[i], con[(l+)%cn]))
{
l = (l+)%cn;
}
tmp = dmul(con[i], con[i+], con[i], con[r]) - dmul(con[i], con[i+], con[i], con[l]);
tmp *= xmul(con[i], con[i+], con[i], con[u]);
tmp /= dist2(con[i], con[i+]);
len = xmul(con[i], con[i+], con[i], con[u])/dist(con[i], con[i+]);
if(sign(tmp - ans) < )
{
ans = tmp;
ds[] = getRoot(con[l], con[i], con[i+]);
ds[] = getRoot(con[r], con[i+], con[i]);
ds[] = change(con[i], con[i+], ds[], len);
ds[] = change(con[i], con[i+], ds[], len);
}
}
}
return ans+eps;
} int main()
{
int t;
scanf("%d",&t);
for(int Cas = ; Cas <=t; ++Cas)
{
printf("Case #%d:\n",Cas);
int num = ;
scanf("%d",&num);
for(int i = ; i < num ; ++i)
{
ps[i*+].read();
ps[i*+].read();
ps[i*+].read();
ps[i*+].read();
}
struct point ds[];
double ans = getMinAreaRect(ps,num*,ds);
printf("%.0lf\n",ans);
}
return ;
}
2015年百度之星初赛(1) --- F 矩形面积的更多相关文章
- 2015年百度之星初赛(1) --- D KPI
KPI Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...
- 2015年百度之星初赛(1) --- C 序列变换
序列变换 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- 2015年百度之星初赛(1) --- B 找连续数
找连续数 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- 2015年百度之星初赛(1) --- A 超级赛亚ACMer
超级赛亚ACMer Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem D ...
- 数学 2015百度之星初赛2 HDOJ 5255 魔法因子
题目传送门 /* 数学:不会写,学习一下这种解题方式:) 思路:设符合条件的数的最高位是h,最低位是l,中间不变的部分为mid,由题意可得到下面的公式(这里对X乘上1e6用a表示,b表示1e6) (h ...
- LIS 2015百度之星初赛2 HDOJ 5256 序列变换
题目传送门 题意:中文题面 分析:LIS(非严格):首先我想到了LIS,然而总觉得有点不对:每个数先减去它的下标,防止下面的情况发生:(转载)加入序列是1,2,2,2,3,这样求上升子序列是3,也就是 ...
- Kruskal 2015百度之星初赛2 HDOJ 5253 连接的管道
题目传送门 /* 最小生成树(Kruskal):以权值为头,带入两个端点,自然的排序;感觉结构体的并查集很好看 注意:题目老头要的是两个农田的高度差,中文水平不好,题意理解成和平均值的高度差! */ ...
- BFS 2015百度之星初赛2 HDOJ 5254 棋盘占领
题目传送门 /* BFS:先把1的入队,每个1和它相邻的组合后看看能不能使0变1,若有则添加入队,change函数返回改变了多少个0 注意:结果还要加上原来占领的 */ #include <cs ...
- 二分搜索 2015百度之星初赛1 HDOJ 5248 序列变换
题目传送门 /* 二分搜索:在0-1e6的范围找到最小的max (ai - bi),也就是使得p + 1 <= a[i] + c or a[i] - c 比赛时以为是贪心,榨干智商也想不出来:( ...
随机推荐
- Ubuntu上安装和使用SSH,Xming+PuTTY在Windows下远程Linux主机使用图形界面的程序
自:http://blog.csdn.net/neofung/article/details/6574002 Ubuntu上安装和使用SSH 网上有很多介绍在Ubuntu下开启SSH服务的文章,但大 ...
- Codeforces Round #385 (Div. 2) B - Hongcow Solves A Puzzle 暴力
B - Hongcow Solves A Puzzle 题目连接: http://codeforces.com/contest/745/problem/B Description Hongcow li ...
- android 常用类
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38965311,本文出自[张鸿洋的博客] 打开大家手上的项目,基本都会有一大批的辅 ...
- java单例之enum实现方式
传统的两私有一公开(私有构造方法.私有静态实例(懒实例化/直接实例化).公开的静态获取方法)涉及线程安全问题(即使有多重检查锁也可以通过反射破坏单例), 目前最为安全的实现单例的方法是通过内部静态en ...
- Eclipse shortcuts
Editor Shortcut Description Alt + / Content assist. A great help for our coding. Ctrl + Shift + F Fo ...
- 2016年象行中国(上海站)圆满结束,会议PPT分享
2016年象行中国(上海站)已于5-21日圆满结束,所有技术交流的文档和PPT经整理后,现集中存放在云盘中,相关议题如下: DeepGreen-LLVM-Intro.pptx ... 1.1M ...
- “HTTPS”安全在哪里?
背景 最近基于兴趣学学习了下 HTTPS 相关的知识,在此记录下学习心得. 在上网获取信息的过程中,我们接触最多的信息加密传输方式也莫过于 HTTPS 了.每当访问一个站点,浏览器的地址栏中出现绿色图 ...
- win7中安装redis
1.下载redis安装版本 https://github.com/rgl/redis/downloads 2.设置环境变量 将redies的安装目录设置为环境变量 参考: http://www.cnb ...
- Android-NDK编译:cocos2d-x(二)
看了看NDK的文档....里面总是莫名的会提下windows需要cygwin环境... 但是cocos2d-x3.0alpha1 中, 编译samples的python脚本 cocos2d-x3/bu ...
- CentOS 6 安装 python 2.7 和 mod_wsgi 运行pyocr[tesseract]
最新版本的tesseract-ocr 3.0.4 需要运行于python2.7版本以上,因此需要升级系统中默认的2.6版本python及Mod_WSGI 1,下载安装Python-2.7.10 > ...