【题解】切割多边形 [SCOI2003] [P4529] [Bzoj1091]
【题解】切割多边形 [SCOI2003] [P4529] [Bzoj1091]
传送门:切割多边形 \(\text{[SCOI2003] [P4529]}\) \(\text{[Bzoj1091]}\)
【题目描述】
给出一个 \(Mx*My\) \((0 < Mx,My < 500)\) 的矩形,现要用 \(n\) \((3 \leqslant n \leqslant 8)\) 条直线依次对其进行切割,将它变成凸 \(n\) 边形,每次切割的长度为该直线在剩下的矩形内部的部分的长度,求最短的切割线总长度。
【分析】
一道计算几何膜您题。
由于 \(n\) 比较小,可以 \(O(n!)\) 枚举切割线的顺序,最后计算总长度取最小值就行了。
但有个非常麻烦的问题:如何求每次加入直线的切割线长度?
考虑用一个栈储存当前已经加入的直线(上下左右四个边界会在最初时加入),如果现在要加入直线 \(p_1-p_2\)(这里为方便描述,设 \(p_1\) 在左边,\(p_2\) 在右边),先求出它与栈中所有直线的交点,然后在这些交点中分别找到:\(p_1\) 左边距离 \(p_1\) 最近的点 \(ans_1\) 和 \(p_2\) 右边距离 \(p_2\) 最近的点\(ans_2\),易知 \(len(ans_1,ans_2)\) 即为当次切割线长度。
图就不画了,自己领会吧。。。
【Code】
#include<algorithm>
#include<cstdio>
#include<cmath>
#define LD double
#define LL long long
#define Re register int
#define Vector Point
using namespace std;
const int N=20;
const LD eps=1e-9,inf=1e9;
inline int dcmp(LD a){return a<-eps?-1:(a>eps?1:0);}//处理精度
inline LD Abs(LD a){return a*dcmp(a);}//取绝对值
struct Point{
LD x,y;Point(LD X=0,LD Y=0){x=X,y=Y;}
inline void in(){scanf("%lf%lf",&x,&y);}
inline void out(){printf("%.2lf %.2lf\n",x,y);}
}p1,p2,p3,p4,P[N];
struct Line{
Point a,b;int id;LD k;Line(Point X=Point(0,0),Point Y=Point(0,0),int ID=0,LD K=0){a=X,b=Y,id=ID,k=K;}
inline void sakura(){k=(!dcmp(a.x-b.x))?0.0:(a.y-b.y)/(a.x-b.x);}
inline bool operator<(Line O)const{return k<O.k;}
}L[N],Q[N];
inline LD Dot(Vector a,Vector b){return a.x*b.x+a.y*b.y;}//点积
inline LD Cro(Vector a,Vector b){return a.x*b.y-a.y*b.x;}//叉积
inline LD Len(Vector a){return sqrt(Dot(a,a));}//模长
inline Point operator+(Point a,Vector b){return Vector(a.x+b.x,a.y+b.y);}
inline Vector operator-(Point a,Point b){return Vector(a.x-b.x,a.y-b.y);}
inline Vector operator*(Vector a,LD b){return Vector(a.x*b,a.y*b);}
inline Point cross_LL(Point a,Point b,Point c,Point d){//两直线AB,CD的交点
Vector x=b-a,y=d-c,z=a-c;
return a+x*(Cro(y,z)/Cro(x,y));//点A加上向量AF
}
int n,t,a[N],vis[N];LD Mx,My,Ans=inf;
inline void dfs(Re g,LD ans){
if(g>n){Ans=min(Ans,ans);return;}
for(Re i=1;i<=n;++i)
if(!vis[i]){
Point p1=L[i].a,p2=L[i].b,ans1=Point(inf,inf),ans2=Point(inf,inf);
//ans1:在p2-p1延长线上距离p1最近的点
//ans2:在p1-p2延长线上距离p2最近的点
for(Re j=1;j<=t;++j){
Point b=cross_LL(p1,p2,Q[j].a,Q[j].b);//获取直线L[i]与Q[i]的交点b
if(dcmp(Len(p1-b)-Len(p2-b))<0&&dcmp(Len(p1-ans1)-Len(p1-b))>0)ans1=b;//如果 len(b,p1)<len(b,p2) 且 len(p1,b)<len(p1,ans1)
if(dcmp(Len(p2-b)-Len(p1-b))<0&&dcmp(Len(p2-ans2)-Len(p2-b))>0)ans2=b;//如果 len(b,p2)<len(b,p1) 且 len(p2,b)<len(p2,ans2)
}
vis[i]=1,Q[++t]=L[i];
dfs(g+1,ans+Len(ans1-ans2));//加上len(ans1,ans2)
vis[i]=0,--t;
}
}
int main(){
// freopen("123.txt","r",stdin);
scanf("%lf%lf%d",&Mx,&My,&n);
for(Re i=1;i<=n;++i)P[i].in();
for(Re i=1;i<=n;++i)L[i]=Line(P[i],P[i<n?i+1:1],i);//获取n条直线
p1=Point(0,0),p2=Point(0,My),p3=Point(Mx,My),p4=Point(Mx,0);//四个顶点
Q[++t]=Line(p1,p2),Q[++t]=Line(p2,p3),Q[++t]=Line(p3,p4),Q[++t]=Line(p4,p1);//先将四个边界入队
dfs(1,0.0);
printf("%.3lf\n",Ans);
}
【题解】切割多边形 [SCOI2003] [P4529] [Bzoj1091]的更多相关文章
- poj 2540 Hotter Colder 切割多边形
/* poj 2540 Hotter Colder 切割多边形 用两点的中垂线切割多边形,根据冷热来判断要哪一半 然后输出面积 */ #include <stdio.h> #include ...
- bzoj1091: [SCOI2003]切割多边形
Description 有一个凸p边形(p<=8),我们希望通过切割得到它.一开始的时候,你有一个n*m的矩形,即它的四角的坐标分别为(0,0), (0,m), (n,0), (n,m).每次你 ...
- 【BZOJ】【1091】【SCOI2003】切割多边形
计算几何+枚举 我比较傻逼……一开始想了个贪心,就是这样:
- 题解 P4302 【[SCOI2003]字符串折叠】
讲讲我的做法 题目大意:对一个字符串进行折叠是它长度最小 看一眼数据范围:哇!字符串长度不超过100!这是一道省选题,不可能给你太宽裕的时限,所以,题目基本暗示你要用\(n^{3}\)多一些的算法复杂 ...
- 任意多边形切割/裁剪(附C#代码实现)
本实现主要参考了发表于2003年<软件学报>的<一个有效的多边形裁剪算法>(刘勇奎,高云,黄有群)这篇论文,所使用的理论与算法大都基于本文,对论文中部分阐述进行了详细解释,并提 ...
- BZOJ 1091--切割多边形(几何&枚举)
1091: [SCOI2003]切割多边形 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 356 Solved: 157[Submit][Status ...
- poj3335 半交平面,多边形内核
Rotating Scoreboard Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 5300 Accepted: 21 ...
- TZOJ 2560 Geometric Shapes(判断多边形是否相交)
描述 While creating a customer logo, ACM uses graphical utilities to draw a picture that can later be ...
- WebGIS裁剪算法-线裁剪多边形
在gis系统中 经常会用到一些裁剪的方法,首先推荐一个非常好用的空间分析JavaScript库--Turf.js,不仅功能强大.使用简单,同时处理速度也很快. Turf.js中提供了一中多边形的裁剪方 ...
随机推荐
- ubutun 服务器配置jupyter notebook
由于能力有限,学习机器学习时候发现,自己的电脑带不起来,所以想起了服务器,选择的是阿里的ubutun服务器,所以希望能够 使用jupyter notebook,看到网上一大片,配置和好久,才成功,在这 ...
- ixgbe 驱动 为xxx驱动做准备1
网卡都是pci设备,因此这里每个网卡驱动其实就是一个pci驱动.并且intel这里是把好几个万兆网卡(82599/82598/x540)的驱动做在一起的.V4L2 一样几个类型摄像头合并在一起 先说一 ...
- ceph各个版本之间参数变化分析
前言 本篇主要是分析ceph的版本之间参数的变化,参数变化意味着功能的变化,通过参数来分析增加,删除,修改了哪些功能,以及版本之间的变化,本篇主要通过导出参数,然后通过脚本去比对不同的版本的参数变化 ...
- PLSQL-解析XML
DECLARE v_xmlclob CLOB := '<?xml version="1.0" encoding="UTF-8"?> <head ...
- Python_错误调试2018.3.17【待完善】
异常处理 几个提示信息: notice 注意 warning 警告 error 错误 debug 调试 错误处理 1.Try语句 try execpt 2.print() 3.assert断言,当满足 ...
- [代码审计]:PhpMyWind储存型XSS漏洞(CVE-2017-12984)
简介 今天开启一下代码审计的篇章 python安全编程剩下的看起来没意思就结束了 ,现在规划每2周写一个爬虫练练手, 然后今天开启代码审计和Docker的学习 我个人感觉先看漏洞利用过程再看漏洞分析 ...
- Appium上下文和H5测试(一)
坚持原创输出,点击蓝字关注我吧 作者:清菡 博客:oschina.云+社区.知乎等各大平台都有. 目录 一.混合应用-H5 1.混合应用是什么? 2.怎么样分辨一个 App 页面究竟是原生的还是 We ...
- 巧用Beyond Compare帮你更好校对文稿
我们平常所说的校对工作,大多数指的是书本.文章出版前的对其进行的原稿比对工作.该工作要求极为细致,校对者需对文稿中的标点.编号.序号等细微部分进行认真比对,以保证出版物的质量.其实我们在日常的学习工作 ...
- 写给程序员的机器学习入门 (九) - 对象识别 RCNN 与 Fast-RCNN
因为这几个月饭店生意恢复,加上研究 Faster-RCNN 用掉了很多时间,就没有更新博客了.这篇开始会介绍对象识别的模型与实现方法,首先会介绍最简单的 RCNN 与 Fast-RCNN 模型,下一篇 ...
- LeetCode双周赛#36
1604. 警告一小时内使用相同员工卡大于等于三次的人 题目链接 题意 给定两个字符串数组keyName和keyTime,分别表示名字为keytime[i]的人,在某一天内使用员工卡的时间(格式为24 ...