题意:给你一个n个点的凸包,让你切一刀,使得它变成一个m边形和一个K边形,问你切的这一刀最短是多少。

如果m+K==n+4,那么一定切在两条边上,但是由于两个线段间的最短距离,至少会经过一条线段的一个端点,于是可以枚举其中一条边,然后算出另一条边,然后枚举4个端点到对面线段的距离,取最小值即可。

如果m+K==n+3,那么一定切在一个点和一个边上,可以枚举那个点,算出顺时针和逆时针方向切到的那条边是谁,然后更新答案。

如果m+K==n+2,那么一定切在两个点上,可以枚举其中一个点,算出顺时针和逆时针方向切到的另外一个点是谁,然后更新答案。

其他情况无解。

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
double ans=99999999999999.0;
struct Point{
int x,y;
Point(const int &x,const int &y){
this->x=x;
this->y=y;
}
Point(){}
double Length(){
return sqrt((double)x*(double)x+(double)y*(double)y);
}
void read(){
scanf("%d%d",&x,&y);
}
}p[105];
typedef Point Vector;
Vector operator - (const Point &a,const Point &b){
return Vector(a.x-b.x,a.y-b.y);
}
int Dot(const Vector &a,const Vector &b){
return a.x*b.x+a.y*b.y;
}
int Cross(const Vector &a,const Vector &b){
return a.x*b.y-a.y*b.x;
}
int n,m,K;
double DisToSegment(Point P,Point A,Point B)
{
Vector v1=B-A,v2=P-A,v3=P-B;
if(Dot(v1,v2)<=0) return v2.Length();
else if(Dot(v1,v3)>0) return v3.Length();
else return fabs((double)Cross(v1,v2))/v1.Length();
}
double Min(double a,double b,double c,double d,double e){
return min(a,min(b,min(c,min(d,e))));
}
//double Min(double a,double b,double c){
// return min(a,min(b,c));
//}
int main(){
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
scanf("%d%d%d",&n,&m,&K);
for(int i=0;i<n;++i){
p[i].read();
}
if(m+K==n+4){
if(m==3 || m==n+1){
puts("0.000");
return 0;
}
for(int i=0;i<n;++i){
int j=(i+m-2)%n;
ans=Min(ans,DisToSegment(p[i],p[j],p[(j+1)%n]),
DisToSegment(p[(i+1)%n],p[j],p[(j+1)%n]),
DisToSegment(p[j],p[i],p[(i+1)%n]),
DisToSegment(p[(j+1)%n],p[i],p[(i+1)%n]));
}
printf("%.3lf\n",ans);
}
else if(m+K==n+3){
for(int i=0;i<n;++i){
int j=(i+m-2)%n;
ans=min(ans,DisToSegment(p[i],p[j],p[(j+1)%n]));
j=(i-(m-2)+n)%n;
ans=min(ans,DisToSegment(p[i],p[j],p[(j-1+n)%n]));
}
printf("%.3lf\n",ans);
}
else if(m+K==n+2){
for(int i=0;i<n;++i){
int j=(i+m-1)%n;
ans=min(ans,(p[i]-p[j]).Length());
j=(i-(m-1)+n)%n;
ans=min(ans,(p[i]-p[j]).Length());
}
printf("%.3lf\n",ans);
}
else{
puts("-1");
}
return 0;
}

最新文章

  1. (转) Android开发性能优化简介
  2. 2016中国&#183;西安“华山杯”WriteUp- SeeSea
  3. EF 保证线程内唯一 上下文的创建
  4. js计算相隔天数日期
  5. linq之将IEnumerable&lt;T&gt;类型的集合转换为DataTable类型 (转载)
  6. LogBack,升级版的log4J
  7. mysql查看表使用的数据库引擎
  8. 苹果的软件/系统盘 网站 http://www.panduoduo.net/u/bd-369186934/2
  9. 烂泥:KVM快照的创建与恢复
  10. jQuery extend() &amp; jQuery.fn.extend(),插件编写
  11. IE6 IE7 IE8(Q) 负边距 (margin) 导致元素溢出 hasLayout 容器时显示异常
  12. Akka Stream文档翻译:Motivation
  13. [poj2762] Going from u to v or from v to u?(Kosaraju缩点+拓排)
  14. elasticsearch 搜索不支持单词的部分进行匹配
  15. Java的I/O总结
  16. C# XmlDocument操作XML
  17. (译)Web是如何工作的:给Web开发新手的初级读物
  18. 在 Confluence 6 中禁用 workbox 应用通知
  19. Python之路(第二十九篇) 面向对象进阶:内置方法补充、异常处理
  20. [java工具类01]__构建格式化输出日期和时间的工具类

热门文章

  1. Git 常用命令(二)
  2. js获取链接参数
  3. centos7系统安装配置
  4. python实战===代码
  5. centos_7.1.1503_src_7
  6. JavaScript自定义事件,动态添加属性
  7. 爬虫基础库之requests
  8. js实现图片下载
  9. AC日记——【模板】点分治(聪聪可可) 洛谷 P2634
  10. nodejs里的express自动刷新高级篇【转载】