BZOJ 1091([SCOI2003]分割多边形-分割直线)
1091: [SCOI2003]分割多边形
Time Limit: 1 Sec Memory Limit: 162 MB id=1091" style="color:blue; text-decoration:none">Status
Submit: 223 Solved: 82
[Submit][
Description
有一个凸p边形(p<=8)。我们希望通过分割得到它。一開始的时候,你有一个n*m的矩形,即它的四角的坐标分别为(0,0), (0,m), (n,0), (n,m)。每次你能够选择一条直线把当前图形分割成两部分,保留当中一个部分(还有一部分扔掉)分割线的长度为此直线在多边形内部的部分的长度。求出最短的分割线总长度。
以下是一个样例。我们须要得到中间的多边形。
分别沿着直线1,2,3。4进行分割就可以,得到中间的四边形。
Input
第一行有两个整数n, m(0 < n,m < 500),第二行为一个整数p(3<=p<=8)。
下面p行每行为两个整数x, y(0 < x < n, 0 < y < m),为按顺时针给出的各顶点坐标。数据保证多边形的是凸的,无三点共线。输入数据无错误。
Output
仅一行,为最短分割线的总长度。四舍五入到小数点后3位。同意有0.001的误差。
Sample Input
4
80 80
70 30
20 20
20 80
Sample Output
HINT
例子相应于图中给出的例子。
Source
直接把多边形伸长成2点都在矩形上的线段,这种话每次取时把之前的线段割一下。
注意伸长时保证向量方向
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Lson (x<<1)
#define Rson ((x<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (1000000007)
#define MP make_pair
#define MAXP (500+10)
#define MAXN (500+10)
#define MAXM (500+10)
#define eps (1e-6)
long long mul(long long a,long long b){return (a*b)%F;}
long long add(long long a,long long b){return (a+b)%F;}
long long sub(long long a,long long b){return (a-b+(a-b)/F*F+F)%F;}
typedef long long ll;
int n,m,p;
double sqr(double x){return x*x;}
int dcmp(double a,double b=0){if (fabs(a-b)<=eps) return 0;else if (a<b) return -1;return 1;}
struct P
{
double x,y;
P(){}
P(double _x,double _y):x(_x),y(_y){}
friend istream& operator>>(istream& cin,P &a){cin>>a.x>>a.y;return cin;}
friend ostream& operator<<(ostream& cout,P &a){cout<<a.x<<' '<<a.y;return cout;}
friend bool operator==(P a,P b){return dcmp(a.x,b.x)==0&&dcmp(a.y,b.y)==0; }
}a[MAXP];
struct V
{
double x,y;
V(){}
V(double _x,double _y):x(_x),y(_y){}
V(P a,P b):x(b.x-a.x),y(b.y-a.y){}
friend V operator*(double a,V b){return V(a*b.x,a*b.y);}
friend V operator-(P a,P b){return V(b.x-a.x,b.y-a.y); }
friend double operator*(V a,V b){return a.x*b.y-a.y*b.x;}
friend double operator^(V a,V b){return a.x*b.x+a.y*b.y;}
friend P operator+(P a,V b){return P(a.x+b.x,a.y+b.y); }
friend double dis2(V a){return sqr(a.x)+sqr(a.y); }
};
struct L
{
P p;
V v;
L(){}
L(P _A,V _B):p(_A),v(_B){}
friend bool parallel(L a,L b) {return (dcmp(a.v.x*b.v.y,a.v.y*b.v.x))==0;}
friend P intersect(L a,L b) //直线交点
{
V &v=a.v,&w=b.v,u=V(b.p,a.p);
double t=(w*u)/(v*w);
P c=a.p+t*v; return c;
}
friend bool inleft(P a,L b){return dcmp(b.v*V(b.p,a))>=0; }
void print(){cout<<p.x<<' '<<p.y<<' '<<v.x<<' '<<v.y<<endl; }
}l[MAXP],lrec[4];
bool inrec(P a){return (dcmp(a.x)>=0&&dcmp(a.x,n)<=0&&dcmp(a.y)>=0&&dcmp(a.y,m)<=0);}
L through_rec_line(L l)
{
int siz=0;P st[3];
if (dcmp(l.v.x)==0) return L(P(l.p.x,l.v.y>0?0:m),V(0,(l.v.y>0?1:-1)*m));
if (dcmp(l.v.y)==0) return L(P(l.v.x>0?0:n,l.p.y),V((l.v.x>0?1:-1)*n,0)); //至此保证不平行坐标系
Rep(i,4)
{
if (parallel(lrec[i],l)) continue;
st[++siz]=intersect(lrec[i],l);
if (!inrec(st[siz])) siz--;
if (siz==2)
{
if (st[1]==st[2]) siz--;
else
{
V a=V(st[1],st[2]);
if (dcmp(a^l.v)<0) return L(st[2],V(st[2],st[1]));
return L(st[1],a);
}
}
}
}
bool b[MAXP]={0};
double ans=1e300;
int cut_list[MAXN];
void dfs(double tot,int siz)
{
if (tot>ans) return;
if (siz==p)
{
// Rep(i,siz) cout<<cut_list[i]<<' ';printf("%.3lf\n",ans);
ans=min(ans,tot);
return;
} /*
if (siz==2)
{
if (cut_list[0]==2&&cut_list[1]==1)
{
cout<<' ';
}
}*/ For(i,p)
if (!b[i])
{
L x=through_rec_line(l[i]);
For(j,p)
if (!parallel(l[j],x)&&b[j])
{
P p=intersect(x,l[j]);
if (dcmp(V(p,x.p)^V(p,x.p+x.v))<0)
{
if (!inleft(x.p,l[j])) x=L(p,V(p,x.p+x.v));
else if (!inleft(x.p+x.v,l[j])) x=L(x.p,V(x.p,p));
}
}
b[i]=1;
cut_list[siz]=i;
/*
Rep(j,siz) printf("\t");
cout<<i<<endl;
printf("%.3lf\n",tot+sqrt(dis2(x.v)));
*/
dfs(tot+sqrt(dis2(x.v)),siz+1);
b[i]=0;
}
}
int main()
{
// freopen("bzoj1091.in","r",stdin);
// freopen("bzoj1091.out","w",stdout); cin>>n>>m>>p;
ForD(i,p) cin>>a[i];memcpy(a+p+1,a+1,sizeof(P)*p);
For(i,p) l[i]=L(a[i],V(a[i],a[i+1]));memcpy(l+p+1,l+1,sizeof(L)*p); lrec[0]=L(P(0,0),V(n,0)),lrec[1]=L(P(n,0),V(0,m)),lrec[2]=L(P(n,m),V(-n,0)),lrec[3]=L(P(0,m),V(0,-m));
For(i,p) l[i]=through_rec_line(l[i]); // For(i,p) l[i].print(); dfs(0,0); printf("%.3lf\n",ans);
return 0;
}
BZOJ 1091([SCOI2003]分割多边形-分割直线)的更多相关文章
- leaflet结合turf.js实现多边形分割(附源码下载)
前言 leaflet 入门开发系列环境知识点了解: leaflet api文档介绍,详细介绍 leaflet 每个类的函数以及属性等等 leaflet 在线例子 leaflet 插件,leaflet ...
- C 语言 字符串命令 strstr()的用法 实现将原字符串以分割串分割输出
C 语言 字符串命令 strstr()的用法 实现将原字符串以分割串分割输出 strstr() 命令是在原字符串中查找指定的字符串第一次出现的地址,用这个特性可以实现字符的分割,判断是否包涵等功能: ...
- 【BZOJ】3675: [Apio2014]序列分割
http://www.lydsy.com/JudgeOnline/problem.php?id=3675 题意:给一个n个数字的序列,每一次分割的贡献是$sum(left, mid)*sum(mid+ ...
- 【BZOJ】1044: [HAOI2008]木棍分割 二分+区间DP
链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1044 Description 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, ...
- 【BZOJ】1044: [HAOI2008]木棍分割(二分+dp)
http://www.lydsy.com/JudgeOnline/problem.php?id=1044 如果只求最大的最小,,直接二分就行了...可是要求方案.. 好神! 我竟然想不到! 因为我们得 ...
- BZOJ:5092 [Lydsy1711月赛]分割序列(贪心&高维前缀和)
Description 对于一个长度为n的非负整数序列b_1,b_2,...,b_n,定义这个序列的能量为:f(b)=max{i=0,1,...,n}((b_1 xor b _2 xor...xor ...
- bzoj 3559: [Ctsc2014]图的分割【最小生成树+并查集】
读题两小时系列-- 在读懂题意之后,发现M(c)就是c这块最大权割边也就是的最小生成树的最大权边的权值,所以整个问题都可以在MST的过程中解决(M和c都是跟着并查集变的) 不过不是真的最小生成树,是合 ...
- 【BZOJ 3675】[Apio2014]序列分割
[链接] 链接 [题意] 在这里输入题意 [题解] 模拟一下样例. 会发现.切的顺序不影响最后的答案. 只要切点确定了. 答案就确定了. 则设f[i][j]表示前i段,第i段保留到j的最大值. \(f ...
- bzoj1091: [SCOI2003]切割多边形
Description 有一个凸p边形(p<=8),我们希望通过切割得到它.一开始的时候,你有一个n*m的矩形,即它的四角的坐标分别为(0,0), (0,m), (n,0), (n,m).每次你 ...
随机推荐
- largest rectangle in histogram leetcode
Given n non-negative integers representing the histogram's bar height where the width of each bar is ...
- 苹果面临起诉:App Store 涉嫌垄断吗?
今日导读 现代社会,手机在手,啥也不愁.购物不用带钱包,网上支付可以搞定一切:旅游懒得背相机,修图 App 帮你打造最美的自己.看直播.学英语.玩游戏.听音乐,我们的生活已经充斥着各类 App.据悉, ...
- 通俗理解 模糊自适应PID
模糊自适应PID算法就是在经典的PID的基础上添加模糊控制规则库,建立这个库的目的就是算法能够自己来进行改变P.I.D的值. 就拿温度的上升过程控制来说,刚开始的时候,希望温度能够快速的升到终点温度, ...
- 在windows下.NET CORE 与Consul简单使用
0)基本概念 consul常用于服务发现 [微服务] web_Api \ \ ->注册服务 raft选举le ...
- C指针类型转换问题
先看下面的代码: #include<stdio.h> int main () { int a; char *x; x = (char *) &a; a = 512; x[0] = ...
- laravel 数据导出
支持:php 7.0 以上 三种方案总结介绍: 第一种:最简单且不会有长久隐患.但不适合数据量多 第二种: 适合中等数据量,不会有长久隐患.但导出时极占内存 第三种:适合大量数据,不会占据 ...
- xmind 8 安装后启动失败(未提示错误信息)
xmind 8 安装后启动失败 前言 家里的计算机也安装了xmind,启动之后界面显示xmind的启动图标,几秒之后启动图标消失(闪退了),然后留我一脸懵逼.想着卸载了安装一个新的应该没有问题 ...
- 360 Atlas中间件安装及使用
1.下载Atlas wget https://github.com/Qihoo360/Atlas/releases/download/2.2.1/Atlas-2.2.1.el6.x86_64.rpm ...
- 条款5:了解C++默默编写并调用哪些函数(Know what functions C++ silently writes and calls)
1.default costructor / copy constructor / copy assignment 者三者的区别? 特别是copy constructor & copy as ...
- pwnable.kr cmd2之write up
来看一下源代码: #include <stdio.h> #include <string.h> int filter(char* cmd){ ; r += strstr(cmd ...