题目链接:

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

求下列点的凸包

求得凸包如下:

Graham扫描算法:

找出最左下的点,设为一号点,将其它点对一号点连线,按照与x轴的夹角大小排序:

让点1,2入栈,从第三个点开始循环

步骤1:判断该点是否在栈顶第二个点和栈顶的点的连线的左边,

2.如果在左边,将该点入栈,继续循环,

3.如果不在,弹出栈顶点,重复步骤1,

3在1,2连线左边,3入栈

4在2,3连线左边,4入栈

5不在3,4连线左边,4出栈,5在2,3连线左边,5入栈

6在3,5连线左边,6入栈

7不在5,6连线左边,6出栈,7在3,5连线左边,7入栈

遍历完成后,将栈顶与1连起来就完成了

代码

//#include<bits/stdc++.h>
#include<iostream>
#include<cmath>
#include<algorithm>
#define fi first
#define se second
#define INF 0x3f3f3f3f
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pqueue priority_queue
#define NEW(a,b) memset(a,b,sizeof(a))
#define lowbit(x) ((x)&(-x))
using namespace std;
const double pi=4.0*atan(1.0);
const double e=exp(1.0);
const int maxn=4e4+;
typedef long long LL;
typedef unsigned long long ULL;
const LL mod=1e9+;
const ULL base=1e7+;
struct Point{
int x,y;
bool operator<(Point &u){//坐标排序
if(x!=u.x) return x<u.x;
return y<u.y;
}
};
Point vex[maxn],Stack[maxn],Basis;
short checkL(Point p,Point q,Point s){//判断点s是否在直线pq的左侧
int area2=p.x*q.y-p.y*q.x+q.x*s.y-q.y*s.x+s.x*p.y-s.y*p.x;
if(area2>) return ;//表示在左侧
if(area2==) return ;//表示在同一条线上;
return -;//表示在右侧
}
double dis(Point u,Point v){//计算uv的距离
return sqrt((u.x-v.x)*(u.x-v.x)*1.0+(u.y-v.y)*(u.y-v.y));
}
bool cmp(Point a,Point b){//极角排序
short m=checkL(Basis,a,b);
if(m==) return ;//b在基点与a的连线的左侧,说明b的极角大于a
if(m==&&dis(Basis,a)<=dis(Basis,b))//极角相同时,靠近基点的排在前
return ;
return ;
}
int main(){
cin.tie();
cout.tie();
int n,l;
cin>>n>>l;
for(int i=;i<n;i++){
cin>>vex[i].x>>vex[i].y;
}
sort(vex,vex+n);
Basis=vex[];//选第一个点为基点
sort(vex+,vex+n,cmp);
int top=;
Stack[top]=vex[];
Stack[++top]=vex[];
for(int i=;i<n;i++){
while(top>=&&checkL(Stack[top-],Stack[top],vex[i])<){
top--;
}
Stack[++top]=vex[i];
}
double sum=0.0;
for(int i=;i<top;i++){
sum+=dis(Stack[i],Stack[i+]);
}
sum+=dis(Stack[top],Stack[]);
sum+=2.0*pi*l;
LL ans=(LL)sum;
if(sum-(double)ans>=0.5){
ans++;
}
cout<<ans<<endl;
system("pause");
return ;
}

最新文章

  1. Windows Store App JavaScript 开发:选取文件和文件夹
  2. Win10/UWP新特性系列—Launcher实现应用间的通信
  3. Oracle LPAD/RPAD函数在处理中文时的注意事项
  4. 加载数据库驱动程序的方法和JDBC的流程
  5. 在汇编代码中调用C函数
  6. windows下编译Libevent
  7. php陷阱:字符串和数字比较
  8. Number对象
  9. 近期Responsive web design项目经验分享
  10. 【SSH 基础】浅谈Hibernate关系映射(4)
  11. day17递归函数(二分法查找)
  12. docker nginx letsencrypt
  13. [小米 Online Judge]找出单独出现的数字
  14. 流形学习(manifold learning)综述
  15. Javascript转义字符串中的特殊字符处理
  16. ATM-JAVA程序 //程序有5处相同错误,找不出原因 转账功能没有实现,修改密码来不及实现了
  17. 学习笔记之TensorFlow
  18. 20155211《网络对抗》Exp02 后门原理与实践
  19. Android开发之获取相册照片和获取拍照照片二
  20. [原]unity3d刀光剑影(二)

热门文章

  1. CCF-URL映射-(正则匹配)-20180303
  2. _proto_ &amp;&amp; prototype (原型 &amp;&amp; 原型链)
  3. ubuntu 16.04 安装 网易云
  4. Java基础之枚举类型
  5. 程序猿大牛 Jeff Atwood 的两本中文书
  6. 4、Linux常用命令
  7. [C#]如何将 string 安全地转换为 int
  8. VUE 微信开发
  9. 【C++】读取参数的类
  10. mysql 将行拼接成字符串的方法