HDU 1348 Wall 【凸包】
<题目链接>
题目大意:
给出二维坐标轴上 n 个点,这 n 个点构成了一个城堡,国王想建一堵墙,城墙与城堡之间的距离总不小于一个数 L ,求城墙的最小长度,答案四舍五入.
解题分析:
求出这些点所围成的凸包,然后所围城墙的长度就为 该凸包周长 + 以该距离为半径的圆的周长。具体证明如下:

下面的模板还没有整理好
Graham 凸包算法
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
#define maxn 1100
const double pi = acos(-1.0); struct Point {
int x, y;
}s[maxn]; int st[maxn], top; int cross(Point p, Point p1, Point p2)
{
return (p1.x - p.x)*(p2.y - p.y) - (p2.x - p.x)*(p1.y - p.y);
} double dist(Point p1, Point p2)
{
double tmp = (p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y);
return sqrt(tmp); } bool cmp(Point p1, Point p2)
{
int tmp = cross(s[], p1, p2);
if (tmp>) return true;
else if (tmp == && dist(s[], p1)<dist(s[], p2)) return true;
else return false;
} void Graham(int n)
{
if (n == ) { top = ; st[] = ; }
if (n == ) { top = ; st[] = ; st[] = ; }
if (n>)
{
int i;
st[] = , st[] = ;
top = ;
for (i = ; i<n; i++)
{
while (top> && cross(s[st[top - ]], s[st[top]], s[i])<) //不习惯s[st[top-1]]这种代码风格的可以改一下
top--;
st[++top] = i;
}
}
} int main()
{
int n, l;
int ncase;
cin >> ncase;
while (ncase--)
{
scanf("%d %d", &n, &l);
Point p0;
scanf("%d%d", &s[].x, &s[].y);
p0.x = s[].x, p0.y = s[].y;
int k = ;
for (int i = ; i < n; i++)
{
scanf("%d%d", &s[i].x, &s[i].y);
if ((p0.y > s[i].y) || (p0.y == s[i].y&&p0.x > s[i].x))
{
p0.x = s[i].x;
p0.y = s[i].y;
k = i;
}
}
s[k] = s[];
s[] = p0; sort(s + , s + n, cmp);
Graham(n);
double ans = ;
for (int i = ; i < top; i++)
{
ans += dist(s[st[i]], s[st[i + ]]);
}
ans += dist(s[st[]], s[st[top]]);
ans += * pi*l;
printf("%d\n", (int)(ans + 0.5));
if (ncase)printf("\n");
}
return ;
}
Andrew算法
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const double Pi=acos(-1.0);
struct Point{
double x,y;
Point(double x=,double y=):x(x),y(y){}
};
typedef Point Vector;
bool operator < (Point a,Point b){return a.x<b.x||(a.x==b.x&&a.y<b.y);} Vector operator - (Point a,Point b){return Vector(a.x-b.x,a.y-b.y);} double Dot(Vector a,Vector b){return a.x*b.x+a.y*b.y;} double Length(Vector a){return sqrt(Dot(a,a));} double Angle(Vector a,Vector b){return acos(Dot(a,b)/Length(a)/Length(b));} Vector Rotate(Vector a,double rad){return Vector(a.x*cos(rad)-a.y*sin(rad),a.x*sin(rad)+a.y*cos(rad));} double Cross(Vector a,Vector b){return a.x*b.y-a.y*b.x;} Point operator + (Point a,Vector b){return Point(a.x+b.x,a.y+b.y);} Point getdot(Point a,Vector b,double ang){return a+Rotate(b,ang);} double getrad(double ang){return Pi*(ang/);} Point ans[],at[];
int nu; double polygonArea(){
int k=;
for(int i=;i<nu;i++){
while(k>&&Cross(ans[k-]-ans[k-],at[i]-ans[k-])<=)k--;
ans[k++]=at[i];
}
int p=k;
for(int i=nu-;i>=;i--){
while(k>p&&Cross(ans[k-]-ans[k-],at[i]-ans[k-])<=)k--;
ans[k++]=at[i];
}
double x=;
k--;
if(k<)return ; //求该凸多边形面积
for(int i=;i<k-;i++)x+=Cross(ans[i]-ans[],ans[i+]-ans[]);
return x/;
} int main(){
int T,n;
double x,y,w,h,ang;
scanf("%d",&T);
while(T--){
double area1=,area2=;
nu=;
scanf("%d",&n);
while(n--){
scanf("%lf%lf%lf%lf%lf",&x,&y,&w,&h,&ang);
area2+=w*h; //area储存所有矩形的总面积
Point a;
ang=-getrad(ang);//因为是顺时针旋转的,所以要是负的。。。。。
at[nu++]=getdot(Point(x,y),Vector(w/,h/),ang);
at[nu++]=getdot(Point(x,y),Vector(-w/,h/),ang);
at[nu++]=getdot(Point(x,y),Vector(w/,-h/),ang);
at[nu++]=getdot(Point(x,y),Vector(-w/,-h/),ang);
}
sort(at,at+nu);
area1=polygonArea();
// printf("%lf %lf\n",area1,area2);
printf("%.1lf %%\n",*area2/area1);
}
return ;
}
2018-08-04
HDU 1348 Wall 【凸包】的更多相关文章
- hdu 1348 Wall (凸包)
Wall Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- hdu 1348 Wall (凸包模板)
/* 题意: 求得n个点的凸包.然后求与凸包相距l的外圈的周长. 答案为n点的凸包周长加上半径为L的圆的周长 */ # include <stdio.h> # include <ma ...
- hdu 1348 Wall(凸包模板题)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1348 Wall Time Limit: 2000/1000 MS (Java/Others) M ...
- hdu 1348 (凸包求周长)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=1348 Wall Time Limit: 2000/1000 MS (Java/Others) Mem ...
- POJ 1113 || HDU 1348: wall(凸包问题)
传送门: POJ:点击打开链接 HDU:点击打开链接 以下是POJ上的题: Wall Time Limit: 1000MS Memory Limit: 10000K Total Submissio ...
- hdu 1348:Wall(计算几何,求凸包周长)
Wall Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- HDU 1348 Wall ( 凸包周长 )
链接:传送门 题意:给出二维坐标轴上 n 个点,这 n 个点构成了一个城堡,国王想建一堵墙,城墙与城堡之间的距离总不小于一个数 L ,求城墙的最小长度,答案四舍五入 思路:城墙与城堡直线长度是相等的, ...
- HDU 1348 Wall
题解:计算凸包周长 #include <iostream> #include <cmath> #include <algorithm> const int size ...
- hdu 1348【凸包模板】
#include<iostream> #include<iostream> #include<algorithm> #include<cmath> us ...
随机推荐
- SAP笔记---非-现存任务/请求XXX上的请求锁定
不管在SAP中的哪个系统在点击修改程序时都有可能出现以下图中的报错: 已找到解决办法,步骤如下: 1,se11中查看tlock表找到以上提到的请求号记录: 2,进入se16n,输入请求号,在事务代码输 ...
- luogu P4744 [Wind Festival]Iron Man
再次感谢题解区大佬的指点 规定\(pre[i]\)表示前缀\(i\)的前缀和,\(sum[i][j]\)表示区间\([i,j]\)之和 令\(f[i][j]\)表示前i个数选出j段的最大值,\(g[i ...
- UVA - 10480 Sabotage【最小割最大流定理】
题意: 把一个图分成两部分,要把点1和点2分开.隔断每条边都有一个花费,求最小花费的情况下,应该切断那些边.这题很明显是最小割,也就是最大流.把1当成源点,2当成汇点,问题是要求最小割应该隔断那条边. ...
- UML 类图 说明
继承关系用空心三角形+实线来表示 关联:就是属性 聚合: 合成:组成 依赖:作为参数存在
- 【逆向工具】IDA使用2-VS2015版本release查找main函数入口,局部变量
VS2015版本release查找main函数入口 vc++开发的程序main或WinMain函数是语法规定的用户入口,而不是应用程序入口.入口代码是mainCRTstartup.wmainCRTSt ...
- 关注网页的更新状况,了解最新的handsup 消息.
// 第一部分是网页截图和源码保存 // upon page load. var fs = require("fs"); var resourceWait = 300, maxRe ...
- totastmessage 触发事件后浮框消失的方法
1. 前言 通过查了官放的文档,发现没有 totastmessage 触发事件后,浮框消失的方法,然后通过研究了下点击关闭时的源码,得到了一个的解决方案. 2. 样例代码如下 $("#dro ...
- wap页面
<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...
- Laravel Cache 的缓存文件在到期后是否会自动删除
验证缓存文件是否会自动删除的目的是,防止产生大量的缓存文件,占满磁盘.因为,我最近越来越多的使用 cache 来缓存各类 token. 使用的是 file 作为 CACHE_DRIVER CACHE_ ...
- django----重定向
urlpatterns = [ re_path(r'^(\w+)(\w+)/$',views.index,name="index"), ] 1.<a href="{ ...