1.poj1113 Wall

题目:http://poj.org/problem?id=1113

题意:用一条线把若干个点包起来,并且线距离任何一个点的距离都不小于r。求这条线的最小距离是多少?

分析:这道题的答案是凸包周长加上一个圆周长,即包围凸包的一个圆角多边形,但是没弄明白那些圆角加起来为什么恰好是一个圆。每个圆角是以凸包对应的顶点为圆心,给定的L为半径,与相邻两条边的切点之间的一段圆弧。每个圆弧的两条半径夹角与对应的凸包的内角互补。假设凸包有n条边,则所有圆弧角之和为180°*n-180°*(n-2)=360°。故,围墙周长为=n条平行于凸包的线段+n条圆弧的长度=凸包周长+围墙离城堡距离L为半径的圆周长。

 #include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn=;
const double eps=1e-;
const double pi=acos(-1.0);
inline double sqr(double x){return x*x;}
int sgn(double x){
if (fabs(x)<eps) return ;
if (x<) return -;
return ;
}
struct point{
double x,y;
point(){}
point(double _x,double _y):x(_x),y(_y){}
//判断两点相同
bool operator ==(const point &b) const{
return sgn(x-b.x)== && sgn(y-b.y)==;
}
//
point operator -(const point &b) const{
return point(x-b.x,y-b.y);
}
//叉积
double operator ^(const point &b) const{
return x*b.y-y*b.x;
}
//点积
double operator *(const point &b) const{
return x*b.x+y*b.y;
}
//重载小于号 (求最左下角的点
bool operator <(const point &b)const{
return sgn(x-b.x)== ? sgn(y-b.y)< : x<b.x;
}
};
struct line{
point s,e;
line(){}
line(point _s,point _e):s(_s),e(_e){}
};
double dis(point a,point b){
return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));
}
struct polygon{
int n;
point p[maxn];
line l[maxn];
void add(point q){
p[n++]=q;
}
void getline(){
for (int i=;i<n;i++)
l[i]=line(p[i],p[(i+)%n]);
}
struct cmp{
point p;
cmp(const point &p0):p(p0){}
bool operator ()(const point &aa,const point &bb){
point a=aa,b=bb;
int d=sgn((a-p)^(b-p));
if (d==){
return sgn(dis(a,p)-dis(b,p))<;
}
return d>;
}
};
//极角排序 先找到左下角的点
//重载好point的'<'
void norm(){
point mi=p[];
for (int i=;i<n;i++) mi=min(mi,p[i]);
sort(p,p+n,cmp(mi));
}
//得到凸包,点编号为0--n-1
void Graham(polygon &convex){
norm();
int &top=convex.n;
top=;
if (n==){
top=; convex.p[]=p[]; return ;
}
if (n==){
top=; convex.p[]=p[]; convex.p[]=p[];
if (convex.p[]==convex.p[]) top--;
return ;
}
convex.p[]=p[]; convex.p[]=p[]; top=;
for (int i=;i<n;i++){
while (top> && sgn((convex.p[top-]-convex.p[top-])^(p[i]-convex.p[top-]))<=) top--;
convex.p[top++]=p[i];
}
if (convex.n== && (convex.p[]==convex.p[])) convex.n--;
}
};
polygon C;
int main(){
int n,L; cin >> n >> L;
double x,y;
for (int i=;i<n;i++){
cin >> x >> y;
C.add(point(x,y));
}
polygon ans;
C.Graham(ans);
ans.getline();
double res=;
for (int i=;i<ans.n;i++) res+=dis(ans.l[i].s,ans.l[i].e);
res+=*pi*L;
printf("%d\n",(int)(res+0.5));
return ;
}

poj1113

(为了套板子,写的很繁琐)

2.poj2007 Scrambled Polygon

题目:http://poj.org/problem?id=2007

题意:求一个凸多边形的凸包。要求起始点为输入的第一个点。

分析:rt。

 #include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const double eps=1e-;
const int maxn=;
inline double sqr(int x){return x*x*1.0;}
int sgn(double x){
if (fabs(x)<eps) return ;
if (x<) return -;
return ;
}
struct point{
int x,y;
point(){}
point(int _x,int _y):x(_x),y(_y){}
bool operator ==(const point &b)const{
return (x==b.x && y==b.y);
}
point operator -(const point &b)const{
return point(x-b.x,y-b.y);
}
int operator ^(const point &b)const{
return x*b.y-y*b.x;
}
int operator *(const point &b)const{
return x*b.x+y*b.y;
}
//重载小于号 (求最左下角的点
bool operator <(const point &b)const{
return sgn((x-b.x)*1.0)== ? sgn((y-b.y)*1.0)< : x<b.x;
}
};
double dis(point a,point b){
return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));
}
struct polygon{
int n;
point p[maxn];
void add(point q){
p[n++]=q;
}
struct cmp{
point p;
cmp(const point &p0):p(p0){}
bool operator ()(const point &aa,const point &bb){
point a=aa,b=bb;
int k=(a-p)^(b-p);int d;
if (k==) d=;else if (k<) d=-; else d=;
if (d==){
return sgn(dis(a,p)-dis(b,p))<;
}
return d>;
}
};
//极角排序 先找到左下角的点
//重载好point的'<'
void norm(){
point mi=p[];
for (int i=;i<n;i++) mi=min(mi,p[i]);
sort(p,p+n,cmp(mi));
}
//得到凸包,点编号为0--n-1
void Graham(polygon &convex){
norm();
int &top=convex.n;
top=;
if (n==){
top=; convex.p[]=p[]; return ;
}
if (n==){
top=; convex.p[]=p[]; convex.p[]=p[];
if (convex.p[]==convex.p[]) top--;
return ;
}
convex.p[]=p[]; convex.p[]=p[]; top=;
for (int i=;i<n;i++){
while (top> && sgn(((convex.p[top-]-convex.p[top-])^(p[i]-convex.p[top-]))*1.0)<=) top--;
convex.p[top++]=p[i];
}
if (convex.n== && (convex.p[]==convex.p[])) convex.n--;
}
};
polygon C;
int main(){
int x,y; point p;
C.n=;
cin >> x >> y; p=point(x,y); C.add(p);
while (cin >> x >> y) C.add(point(x,y));
polygon ans;
C.Graham(ans); int k;
for (int i=;i<ans.n;i++) if (ans.p[i]==p){k=i;break;}
for (int i=;i<ans.n;i++){
printf("(%d,%d)\n",ans.p[(k+i)%ans.n].x,ans.p[(k+i)%ans.n].y);
}
return ;
}

poj2007

3.poj1228

  题目:http://poj.org/problem?id=1228

题意:输入一个凸包上的点(没有凸包内部的点,要么是凸包顶点,要么是凸包边上的点),判断这个凸包是否稳定。所谓稳定就是判断能不能在原有凸包上加点。

分析:问凸包是否稳定。

 #include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const double eps=1e-;
const int maxn=;
int sgn(double x){
if (fabs(x)<eps) return ;
if (x<) return -;
return ;
}
struct point{
double x,y;
point(){}
point(double _x,double _y):x(_x),y(_y){}
point operator -(const point &b)const{
return point(x-b.x,y-b.y);
}
double operator ^(const point &b)const{
return x*b.y-y*b.x;
}
}p[maxn],pp[maxn];
bool cmp(point a,point b) {return a.x < b.x || (a.x == b.x && a.y < b.y);}
int convexhull(point p[],int n,point pp[]){
sort(p,p+n,cmp);
int m=;
for (int i=;i<n;i++){
while (m> && ((pp[m-]-pp[m-])^(p[i]-pp[m-]))<) m--;
pp[m++]=p[i];
}
int k=m;
for (int i=n-;i>=;i--){
while (m>k && ((pp[m-]-pp[m-])^(p[i]-pp[m-]))<) m--;
pp[m++]=p[i];
}
return m-;
}
bool check(point p[],int n){
for (int i=;i<n-;i++){
if (((p[i-]-p[i])^(p[i+]-p[i]))!= &&
((p[i]-p[i+])^(p[i+]-p[i+]))!=) return false; //保证至少有三个点在同一条边上
}
return true;
}
int main(){
int t,n; double x,y; cin >> t;
while (t--){
cin >> n;
for (int i=;i<n;i++) cin >> p[i].x >> p[i].y;
if (n<){cout << "NO\n";continue;}
int cnt=convexhull(p,n,pp);
if (check(pp,cnt)) cout << "YES\n"; else cout << "NO\n";
}
return ;
}

poj1228

4

5.poj3348 Cows

题目:http://poj.org/problem?id=3348

题意:给出一些点圈出一个最大面积每50平方养一头牛问最多能养多少牛。

分析:凸包+多边形面积。

 #include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn=;
inline int sqr(int x){return x*x;}
struct point{
int x,y;
point(){}
point(int _x,int _y):x(_x),y(_y){}
//判断两点相同
bool operator ==(const point &b) const{
return x-b.x== && y-b.y==;
}
//
point operator -(const point &b) const{
return point(x-b.x,y-b.y);
}
//叉积
int operator ^(const point &b) const{
return x*b.y-y*b.x;
}
//点积
int operator *(const point &b) const{
return x*b.x+y*b.y;
}
//重载小于号 (求最左下角的点
bool operator <(const point &b)const{
return x-b.x==?y-b.y<:x<b.x;
}
};
struct line{
point s,e;
line(){}
line(point _s,point _e):s(_s),e(_e){}
};
int dis(point a,point b){
return (int)sqrt(1.0*sqr(a.x-b.x)+1.0*sqr(a.y-b.y));
}
struct polygon{
int n;
point p[maxn];
void add(point q){p[n++]=q;}
struct cmp{
point p;
cmp(const point &p0):p(p0){}
bool operator ()(const point &aa,const point &bb){
point a=aa,b=bb;
int k=(a-p)^(b-p);
if (k==){
return dis(a,p)-dis(b,p)<;
}
return k>;
}
};
//极角排序 先找到左下角的点
//重载好point的'<'
void norm(){
point mi=p[];
for (int i=;i<n;i++) mi=min(mi,p[i]);
sort(p,p+n,cmp(mi));
}
//得到凸包,点编号为0--n-1
void Graham(polygon &convex){
norm();
int &top=convex.n;
top=;
if (n==){
top=; convex.p[]=p[]; return ;
}
if (n==){
top=; convex.p[]=p[]; convex.p[]=p[];
if (convex.p[]==convex.p[]) top--;
return ;
}
convex.p[]=p[]; convex.p[]=p[]; top=;
for (int i=;i<n;i++){
while (top> && ((convex.p[top-]-convex.p[top-])^(p[i]-convex.p[top-]))<=) top--;
convex.p[top++]=p[i];
}
if (convex.n== && (convex.p[]==convex.p[])) convex.n--;
}
int getarea(){
int sum=;
for (int i=;i<n;i++) sum+=(p[i]^(p[(i+)%n]));
return sum/;
}
};
polygon C;
int main(){
int n,x,y; cin >> n; C.n=;
for (int i=;i<n;i++){
cin >> x >> y;
C.add(point(x,y));
}
polygon ans; C.Graham(ans);
cout << ans.getarea()/ << endl;
return ;
}

poj3348

6.poj1259/hdoj6219

题意:给出n个点,求出最大面积的凸包且凸包内不包含原点集中的点。

分析:rt。求最大面积空凸包。

 #include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const double eps=1e-;
const int maxn=;
inline double sqr(double x){return x*x;}
int sgn(double x){
if (fabs(x)<eps) return ;
if (x<) return -;
return ;
}
struct point{
double x,y;
point(){}
point(double _x,double _y):x(_x),y(_y){}
//判断两点相同
bool operator ==(const point &b) const{
return sgn(x-b.x)== && sgn(y-b.y)==;
}
//
point operator -(const point &b) const{
return point(x-b.x,y-b.y);
}
//叉积
double operator ^(const point &b) const{
return x*b.y-y*b.x;
}
//点积
double operator *(const point &b) const{
return x*b.x+y*b.y;
}
//重载小于号 (求最左下角的点
bool operator <(const point &b)const{
return sgn(x-b.x)== ? sgn(y-b.y)< : x<b.x;
}
}p[maxn],pp[maxn];
point tmp;
double dp[maxn][maxn];
double empty_convex(point p[],int n,point o){
double ans=;
for (int i=;i<n;i++) for (int j=;j<n;j++) dp[i][j]=;
for (int i=;i<n;i++){
int j=i-;
while (j>= && ((p[i]-o)^(p[j]-o))==) j--;
bool flag=(j==i-);
while (j>=){
int k=j-;
while (k>= && ((p[i]-p[k])^(p[j]-p[k]))>) k--;
double area=fabs((p[i]-o)^(p[j]-o))/2.0;
if (k>=) area+=dp[j][k];
if (flag) dp[i][j]=area;
ans=max(ans,area);
j=k;
}
if (flag){
for (int j=;j<i;j++) dp[i][j]=max(dp[i][j],dp[i][j-]);
}
}
return ans;
}
double dist(point a,point b){
return sqrt((a-b)*(a-b));
}
bool cmp_angle(point a,point b){
double res=(a-tmp)^(b-tmp);
if (res) return res>;
return dist(a,tmp)<dist(b,tmp);
}
double largest_empty_convex(point p[],int n){
double ans=;
for (int i=;i<n;i++){
tmp=p[i];
int cnt=;
for (int j=;j<n;j++){
if (p[j].y>tmp.y || p[j].y==tmp.y && p[j].x>tmp.x) pp[cnt++]=p[j];
}
sort(pp,pp+cnt,cmp_angle); //根据极角排序
ans=max(ans,empty_convex(pp,cnt,tmp));
}
return ans;
}
int main(){
int t,n; cin >> t;
while (t--){
cin >> n;
for (int i=;i<n;i++) cin >> p[i].x >> p[i].y;
double ans=largest_empty_convex(p,n);
printf("%.1f\n",ans);
}
return ;
}

poj1259

【kuangbin专题】计算几何_凸包的更多相关文章

  1. 凸多边形 HRBUST - 1429 计算几何_凸包_未调完

    任选一个点作为起始点,将其他点按与该点连线的极角排序,二分查询点在哪两个射线之间, 并特别判断一下边界即可. Code: #include <cstdio> #include <al ...

  2. hrbustoj 1318:蛋疼的蚂蚁(计算几何,凸包变种,叉积应用)

    蛋疼的蚂蚁 Time Limit: 1000 MS     Memory Limit: 65536 K Total Submit: 39(22 users)    Total Accepted: 26 ...

  3. poj 1696:Space Ant(计算几何,凸包变种,极角排序)

    Space Ant Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 2876   Accepted: 1839 Descrip ...

  4. [kuangbin]专题六 最小生成树 题解+总结

    kuangbin专题链接:https://vjudge.net/article/752 kuangbin专题十二 基础DP1 题解+总结:https://www.cnblogs.com/RioTian ...

  5. 【kuangbin专题】计算几何_半平面交

    1.poj3335 Rotating Scoreboard 传送:http://poj.org/problem?id=3335 题意:就是有个球场,球场的形状是个凸多边形,然后观众是坐在多边形的边上的 ...

  6. kuangbin专题十三-基础计算几何

    链接:https://cn.vjudge.net/contest/68968 POJ 2318 TOYS 题意:m个玩具落在n+1个区间,给你玩具的坐标,问每个区间有多少玩具. 思路:叉积的简单应用, ...

  7. 计算几何(凸包):SHTSC 2012 信用卡凸包

    这道题是水题,发现平移某些边,答案就是圆心的凸包+一个圆的周长. 不要忽视精度误差! #include <algorithm> #include <iostream> #inc ...

  8. 【kuangbin专题】计算几何基础

    1.poj2318 TOYS 传送:http://poj.org/problem?id=2318 题意:有m个点落在n+1个区域内.问落在每个区域的个数. 分析:二分查找落在哪个区域内.叉积判断点与线 ...

  9. 【kuangbin】计算几何部分最新模板

    二维几何部分 // `计算几何模板` ; const double inf = 1e20; const double pi = acos(-1.0); ; //`Compares a double t ...

随机推荐

  1. spring boot所有配置

    转载 http://blog.csdn.net/lpfsuperman/article/details/78287265 # 日志配置# 日志配置文件的位置. 例如对于Logback的`classpa ...

  2. iOS中堆和栈的区别

    管理方式: 对于栈来讲,是由编译器自动管理,无需我们手工控制:对于堆来讲,释放工作有程序员控制,容易产生memory Leak. 申请大小: 栈:在Windows下,栈是向低地址扩展的数据结构,是一块 ...

  3. normalized

    共同点:实现规范化,让一个向量保持相同的方向,但它的长度为1.0,如果这个向量太小而不能被规范化,一个零向量将会被返回. 不同点:Vector3.normalized的作特点是当前向量是不改变的并且返 ...

  4. 2019.01.14 bzoj2752: [HAOI2012]高速公路(线段树)

    传送门 线段树菜题. 题意简述:给一条nnn个点的链,链有边权,支持区间修改边权,查询在一段区间内随机选择不同的起点和终点路径的期望总边权和. 思路:考虑每条边的贡献. 考虑对于一段区间[l,r][l ...

  5. Codeforces Round #524 (Div. 2) E. Sonya and Matrix Beauty(字符串哈希,马拉车)

    https://codeforces.com/contest/1080/problem/E 题意 有一个n*m(<=250)的字符矩阵,对于每个子矩阵的每一行可以任意交换字符的顺序,使得每一行每 ...

  6. Object.create() 创建实例对象

    var person1 = { name: '张三', age: 38, greeting: function() { console.log('Hi! I\'m ' + this.name + '. ...

  7. shell字符串分割截取和转换总结

    一:字符串的截取 假定有定义变量VAR=mm/aa/bb/dd 1.获取字符串长度:echo "${#VAR}",即输出11: 2.非贪婪模式删除左边的,保留右边的:echo &q ...

  8. GPS 编程笔记

    1.在GPS系统内,经纬度的显示方式一般都可以根据自己的爱好选择,一般有"hddd.ddddd"(度.度),"hddd*mm.mmm"(度.分. 分),&quo ...

  9. 知识点:CSS代码语法

    css 样式由选择符和声明组成,而声明又由属性和值组成,如下图所示: 选择符:又称选择器,指明网页中要应用样式规则的元素,如本例中是网页中所有的段(p)的文字将变成蓝色,而其他的元素(如ol)不会受到 ...

  10. DOS下如何打开程序

    cd c:    #先切回主盘,因为最开始在C:\Users\Administrator这个目录下 cd “指定文件所在的盘:”      #切换到文件所在盘 print "文件目录&quo ...