思路:

我们需要枚举展开多少条边 然后把上底面的点放到和下底面一个平面 然后算两点之间的距离 注意判断直线与线段是否有交点

#include <bits/stdc++.h>

using namespace std;
const double eps = 1e-8;
const double inf = 1e20;
const double pi = acos(-1.0);
const int N = 1e5+7;
//Compares a double to zero
int sgn(double x){
if(fabs(x) < eps)return 0;
if(x < 0)return-1;
else return 1;
}
//square of a double
inline double sqr(double x){return x*x;} struct Point{
double x,y;
Point(){}
Point(double _x,double _y){
x = _x;
y = _y;
}
void input(){
scanf("%lf%lf",&x,&y);
}
void output(){
printf("%.2f-%.2f\n",x,y);
}
bool operator == (Point b)const{
return sgn(x-b.x) == 0 && sgn(y-b.y) == 0;
}
bool operator < (Point b)const{
return sgn(x-b.x)== 0-sgn(y-b.y)?0:x<b.x;
}
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;
}
//返回长度
double len(){
return hypot(x,y);//库函数
}
//返回长度的平方
double len2(){
return x*x + y*y;
}
//返回两点的距离
double distance(Point p){
return hypot(x-p.x,y-p.y);
}
Point operator +(const Point &b)const{
return Point(x+b.x,y+b.y);
}
Point operator *(const double &k)const{
return Point(x*k,y*k);
}
Point operator /(const double &k)const{
return Point(x/k,y/k);
}
//计算 pa 和 pb 的夹角
//就是求这个点看 a,b 所成的夹角
//测试 LightOJ1203
double rad(Point a,Point b){
Point p = *this;
return fabs(atan2( fabs((a-p)^(b-p)),(a-p)*(b-p) ));
}
//化为长度为 r 的向量
Point trunc(double r){
double l = len();
if(!sgn(l))return *this;
r /= l;
return Point(x*r,y*r);
}
//逆时针旋转 90 度
Point rotleft(){
return Point(-y,x);
}
//顺时针旋转 90 度
Point rotright(){
return Point(y,-x);
}
//绕着 p 点逆时针旋转 angle
Point rotate(Point p,double angle){
Point v = (*this)-p;
double c = cos(angle), s = sin(angle);
return Point(p.x + v.x*c-v.y*s,p.y + v.x*s + v.y*c);
}
}p[N];
struct Line{
Point s,e;
Line(){}
Line(Point _s,Point _e){
s = _s;
e = _e;
}
bool operator ==(Line v){
return (s == v.s)&&(e == v.e);
}
//根据一个点和倾斜角 angle 确定直线,0<=angle<pi
Line(Point p,double angle){
s = p;
if(sgn(angle-pi/2) == 0){
e = (s + Point(0,1));
}
else{
e = (s + Point(1,tan(angle)));
}
}
//ax+by+c=0
Line(double a,double b,double c){
if(sgn(a) == 0){
s = Point(0,-c/b);
e = Point(1,-c/b);
}
else if(sgn(b) == 0){
s = Point(-c/a,0);
e = Point(-c/a,1);
}
else{
s = Point(0,-c/b);
e = Point(1,(-c-a)/b);
}
}
void input(){
s.input();
e.input();
}
void adjust(){
if(e < s){
swap(s,e);
}
}
//求线段长度
double length(){
return s.distance(e);
}
//返回直线倾斜角 0<=angle<pi
double angle(){
double k = atan2(e.y-s.y,e.x-s.x);
if(sgn(k) < 0)k += pi;
if(sgn(k-pi) == 0)k-= pi;
return k;
}
//点和直线关系
//1 在左侧
//2 在右侧
//3 在直线上
int relation(Point p){
int c = sgn((p-s)^(e-s));
if(c < 0)return 1;
else if(c > 0)return 2;
else return 3;
}
// 点在线段上的判断
bool pointonseg(Point p){
return sgn((p-s)^(e-s)) == 0 && sgn((p-s)*(p-e)) <= 0;
}
//两向量平行 (对应直线平行或重合)
bool parallel(Line v){
return sgn((e-s)^(v.e-v.s)) == 0;
}
//两线段相交判断
//2 规范相交
//1 非规范相交
//0 不相交
int segcrossseg(Line v){
int d1 = sgn((e-s)^(v.s-s));
int d2 = sgn((e-s)^(v.e-s));
int d3 = sgn((v.e-v.s)^(s-v.s));
int d4 = sgn((v.e-v.s)^(e-v.s));
if( (d1^d2)==-2 && (d3^d4)==-2 )return 2;
return (d1==0 && sgn((v.s-s)*(v.s-e))<=0) ||
(d2==0 && sgn((v.e-s)*(v.e-e))<=0) ||
(d3==0 && sgn((s-v.s)*(s-v.e))<=0) ||
(d4==0 && sgn((e-v.s)*(e-v.e))<=0);
}
//直线和线段相交判断
//-*this line -v seg
//2 规范相交
//1 非规范相交
//0 不相交
int linecrossseg(Line v){
int d1 = sgn((e-s)^(v.s-s));
int d2 = sgn((e-s)^(v.e-s));
if((d1^d2)==-2) return 2;
return (d1==0||d2==0);
}
//两直线关系
//0 平行
//1 重合
//2 相交
int linecrossline(Line v){
if((*this).parallel(v))
return v.relation(s)==3;
return 2;
}
//求两直线的交点
//要保证两直线不平行或重合
Point crosspoint(Line v){
double a1 = (v.e-v.s)^(s-v.s);
double a2 = (v.e-v.s)^(e-v.s);
return Point((s.x*a2-e.x*a1)/(a2-a1),(s.y*a2-e.y*a1)/(a2-a1
));
}
//点到直线的距离
double dispointtoline(Point p){
return fabs((p-s)^(e-s))/length();
}
//点到线段的距离
double dispointtoseg(Point p){
if(sgn((p-s)*(e-s))<0 || sgn((p-e)*(s-e))<0)
return min(p.distance(s),p.distance(e));
return dispointtoline(p);
}
//返回线段到线段的距离
//前提是两线段不相交,相交距离就是 0 了
double dissegtoseg(Line v){
return min(min(dispointtoseg(v.s),dispointtoseg(v.e)),min(v
.dispointtoseg(s),v.dispointtoseg(e)));
}
//返回点 p 在直线上的投影
Point lineprog(Point p){
return s + ( ((e-s)*((e-s)*(p-s)))/((e-s).len2()) );
}
//返回点 p 关于直线的对称点
Point symmetrypoint(Point p){
Point q = lineprog(p);
return Point(2*q.x-p.x,2*q.y-p.y);
}
};
double sum[N],ans=1e18;
int s,t;
void work(Point x,Line tmp,int i){
Line res=Line(x,p[t]);
//printf("%lf\n",res.length());
if(res.linecrossseg(tmp)!=0){
ans=min(ans,res.length());
}
}
int main(){
int n,h;
scanf("%d%d",&n,&h);
for(int i=0;i<n;i++){
p[i].input();
}
scanf("%d%d",&s,&t);
--s; --t;
for(int i=1;i<n;i++){
sum[i]=sum[i-1]+p[i-1].distance(p[i]);
}
double tot=sum[n]=sum[n-1]+p[n-1].distance(p[0]);
for(int i=0;i<n;i++){
Point x=p[i],y=p[(i+1)%n];
Point z=(x-y).rotleft();
z=z*(h*1.0/z.len()); Point t=y+z; Line tmp=Line(t,t+z.rotleft());
//printf("%lf\n",tot);
double len;
if(s>=i+1){
len=sum[s]-sum[i+1];
}else{
len=tot-sum[i+1]+sum[s];
}
Point l,r;
l=t+(tmp.e-tmp.s)/tmp.length()*len;
r=t+(tmp.e-tmp.s)/tmp.length()*(len-tot);
// cout<<i<<" "<<r.x<<" "<<r.y<<endl;
work(l,Line(x,y),i);
work(r,Line(x,y),i);
}
printf("%.6lf\n",ans);
}

最新文章

  1. jQuery $(document).ready() 与window.onload的区别
  2. Qt 信号槽如何传递参数(或带参数的信号槽)
  3. 谷歌的网页排序算法(PageRank Algorithm)
  4. tomcant报错The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path
  5. JSP内置对象整理(转)
  6. SSH三大框架的各自工作流程
  7. quartz定时格式配置以及JS验证
  8. java 编程性能调优
  9. org.hibernate.boot.MappingNotFoundException: Mapping (RESOURCE) not found :
  10. 浅谈css3长度单位rem,以及移动端布局技巧
  11. [CQOI2015]任务查询系统 主席树
  12. 【Raspberry Pi】openwrt 路由
  13. WebKit.net最简单使用方法
  14. 利用node中的内置模块fs实现对简单文件的读取 拷贝 创建等功能
  15. Oracle的归档日志
  16. 160518、java中使用百度地图(超级简单)
  17. CC 攻击检测研究现状
  18. centos7 showdoc 手动安装部署
  19. C#利用phantomJS抓取AjAX动态页面
  20. java 获取url及url参数解析

热门文章

  1. Java并发包源码学习系列:ReentrantLock可重入独占锁详解
  2. 离散傅里叶变换DFT入门
  3. 想学Python不知如何入门,教你!
  4. 如何实现一个简易版的 Spring - 如何实现 Constructor 注入
  5. Linux 用户操作之用户管理 (用户增删改操作)
  6. MySQL select if 查询最后一个主键 id
  7. 【Vue】Vue开发环境搭建
  8. 【Web】HTML入门小结
  9. 【Spring】 Spring的核心容器
  10. C/C++内存对齐详解