1091: [SCOI2003]分割多边形

Time Limit: 1 Sec  Memory Limit: 162 MB

Submit: 223  Solved: 82

[Submit][

id=1091" style="color:blue; text-decoration:none">Status]

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

100 100

4

80 80

70 30

20 20

20 80

Sample Output

312.575

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]分割多边形-分割直线)的更多相关文章

  1. leaflet结合turf.js实现多边形分割(附源码下载)

    前言 leaflet 入门开发系列环境知识点了解: leaflet api文档介绍,详细介绍 leaflet 每个类的函数以及属性等等 leaflet 在线例子 leaflet 插件,leaflet ...

  2. C 语言 字符串命令 strstr()的用法 实现将原字符串以分割串分割输出

    C 语言 字符串命令 strstr()的用法 实现将原字符串以分割串分割输出 strstr() 命令是在原字符串中查找指定的字符串第一次出现的地址,用这个特性可以实现字符的分割,判断是否包涵等功能: ...

  3. 【BZOJ】3675: [Apio2014]序列分割

    http://www.lydsy.com/JudgeOnline/problem.php?id=3675 题意:给一个n个数字的序列,每一次分割的贡献是$sum(left, mid)*sum(mid+ ...

  4. 【BZOJ】1044: [HAOI2008]木棍分割 二分+区间DP

    链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1044 Description 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, ...

  5. 【BZOJ】1044: [HAOI2008]木棍分割(二分+dp)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1044 如果只求最大的最小,,直接二分就行了...可是要求方案.. 好神! 我竟然想不到! 因为我们得 ...

  6. 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 ...

  7. bzoj 3559: [Ctsc2014]图的分割【最小生成树+并查集】

    读题两小时系列-- 在读懂题意之后,发现M(c)就是c这块最大权割边也就是的最小生成树的最大权边的权值,所以整个问题都可以在MST的过程中解决(M和c都是跟着并查集变的) 不过不是真的最小生成树,是合 ...

  8. 【BZOJ 3675】[Apio2014]序列分割

    [链接] 链接 [题意] 在这里输入题意 [题解] 模拟一下样例. 会发现.切的顺序不影响最后的答案. 只要切点确定了. 答案就确定了. 则设f[i][j]表示前i段,第i段保留到j的最大值. \(f ...

  9. bzoj1091: [SCOI2003]切割多边形

    Description 有一个凸p边形(p<=8),我们希望通过切割得到它.一开始的时候,你有一个n*m的矩形,即它的四角的坐标分别为(0,0), (0,m), (n,0), (n,m).每次你 ...

随机推荐

  1. AndroidStudio连不上天天模拟器

    问题:天天模拟器经常无法被Android Studio读取出来: 解决方法:手动连接它的端口: 方法一:找到Android\SDK\platform-tools目录,在当前目录下打开命令行窗口(shi ...

  2. 洛谷 P1085 不高兴的津津

    这道题就是经典的条件分支的题https://www.luogu.org/problemnew/show/P1085 code: #include <stdio.h> int main() ...

  3. [LOJ] 分块九题 3

    https://loj.ac/problem/6279 区间修改,区间查询前驱. TLE无数,我觉得这代码最精髓的就是block=1000. 谜一样的1000. 两个启示: 块内可以维护数据结构,比如 ...

  4. h5 页面 禁止网页缩放

    //禁用双指缩放: document.documentElement.addEventListener('touchstart', function (event) { if (event.touch ...

  5. 新建oracle连接远程服务

    更新下面两个文件夹中的 D:\app\shisan\product\11.2.0\client_1\network\admin D:\ORACLE\product\11.2.0\dbhome_1\NE ...

  6. asp网页无法打开

    环境:Window 2003.IIS6.Framework1.1 .VS2003 一个WebForm项目里面包含一些asp网页  运行后发现asp页面无法访问 提示:无法找到该页 解决方案: 1. [ ...

  7. C#中为什么不能再方法里定义静态变量(Static)

    c#的静态变量是在对象生成的时候分配内存空间的,而不是函数执行的时候. 如果在函数里定义,那么这个变量就需要在函数执行的时候分配内存空间,这是C#不允许的,至于为什么不允许,个是因为垃圾回收机制的问题 ...

  8. HDU-1020-Encoding,题意不清,其实很水~~

    Encoding Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) http:// ...

  9. Go函数学习

    package main import ( "fmt" "reflect" "runtime" "math" ) //函 ...

  10. 2016 Multi-University Training Contest 4 solutions BY FZU

    1001 Another Meaning 对于这个问题,显然可以进行DP: 令dp[i]表示到i结尾的字符串可以表示的不同含义数,那么考虑两种转移: 末尾不替换含义:dp[i - 1] 末尾替换含义: ...