FZU 1015 土地划分
来源:互联网 发布:华为ip地址mac绑定 编辑:程序博客网 时间:2024/04/29 18:58
题目链接:http://acm.fzu.edu.cn/problem.php?pid=1015
解题思路:就是求 n 条线段能将矩形划分成多少个区域。
首先分析直线划分区域的情况,根据已知的结论:平面上 n 条直线最多可以将平面分成 f ( n ) 个区域, 其中 f ( n ) = ( n * n + n + 2 ) / 2。
我们用数学归纳法证明一下:当 n = 1 时,f ( n ) = 2显然成立,即一条直线把平面分成两个区域。假设对于所有的 n < k 的 n,均有
f ( n ) = ( n * n + n + 2 ) / 2。考虑当 n = k,新的直线 l 最多可以和原来的 n-1 条直线有 n - 1 个交点,这 n - 1 个交点将直线分成了 n 段,
其中 n - 2 段为线段,两段为射线。这 n 段线将其所在的 n 个区域一分为二,这样就增加了 n 个区域,所以 f ( n ) = f ( n - 1) + n。
再由归纳假设 f ( n - 1 ) = ( ( n-1 ) * ( n - 1 ) + ( n - 1 ) + 2 ) / 2,
因而有: f ( n ) = ( ( n-1 ) * ( n - 1 ) + ( n - 1 ) + 2 ) / 2 + n = ( n * n + n + 2 ) / 2。所以对所有的正整数 n 都有 f ( n ) = ( n * n + n + 2 ) / 2。
以上证明的关键部分是归纳出 f ( n ) = f ( n - 1 ) + n 的过程。因为线段划分矩形问题与直线划分平面的问题是类似的,所以解题思路也是类似的。
设 f ( n ) 为前 n 条输入的线段将矩形分成区域的个数,1 <= n <= L ,L为线段总数。边界:f ( 1 ) = 2,即一条线段将矩形分成两个区域。
递推:假设已经处理了 n - 1 条线段,新线段为 l ,它和已有的 n - 1 条线段交有 t ' ( n ) 个交点。注意:有些交点在矩形的边界上,
这些交点也是线段的端点,必须将其排除,于是剩下 t ( n ) 个交点。 由于题目限定“任意三点不共线”,因此这些交点将 l 分成 t ( n ) + 1 条线段。
这 t ( n ) + 1 条线段将所在区域一分为二,这样就增加了 t ( n ) + 1 个区域,所以 f ( n ) = f ( n - 1 ) + t ( n ) + 1,则得到 f ( n ) 的递推式;
f ( n ) = f ( 1 ) + [ t ( 2) + t ( 3 ) +… + t ( n ) ] + n - 1 。令输入的 L 条线段之间不在矩形边上的交点个数为 T ,则 T = t ( 2) + t ( 3 ) +… + t ( n )。
所以:f ( L ) = f ( 1 ) + T + L +1,也就是说问题的答案就是线段的条数加上交点的个数再加上 1 。其中L是已知的,问题转化为求 L 条线段之间
交点(不在矩形边界上)的个数。
代码如下:
#include<cstdio>#include<cmath>#include<cstdlib>#include<algorithm>#include<cstring>using namespace std;#define N 100struct point{ int x; int y;};struct Vector{ point s; point e;};point p[N];Vector v[N];#define EPS 1e-6double multi(point p1,point p2,point p0){ return ((p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x));}int Equal_Point(point p1,point p2){ return(abs(p1.x-p2.x)<EPS && abs(p1.y-p2.y)<EPS);}bool Isinside(Vector v1,Vector v2){ if(max(v1.s.x,v1.e.x)>=min(v2.s.x,v2.e.x) && max(v2.s.x,v2.e.x)>=min(v1.s.x,v1.e.x) && max(v1.s.y,v1.e.y)>=min(v2.s.y,v2.e.y) && max(v2.s.y,v2.e.y)>=min(v1.s.y,v1.e.y) && multi(v2.s,v1.e,v1.s) * multi(v1.e,v2.e,v1.s) >=0 && multi(v1.s,v2.e,v2.s) * multi(v2.e,v1.e,v2.s) >=0) return true; return false;}bool Across(Vector v1,Vector v2){ if(Isinside(v1,v2) && !Equal_Point(v1.e,v2.s) && !Equal_Point(v1.s,v2.s) && !Equal_Point(v1.e,v2.e) && !Equal_Point(v1.s,v2.e)) return true; return false;}int main(){ int w,h; while(~scanf("%d%d",&w,&h) && w+h) { int l; scanf("%d",&l); l++; for(int i=0;i<l;i++) { scanf("%d %d",&p[i].x,&p[i].y); if(i==0) { v[i].s.x=p[i].x; v[i].s.y=p[i].y; } else { v[i].e.x=p[i].x; v[i].e.y=p[i].y; v[i+1].s.x=p[i].x; v[i+1].s.y=p[i].y; } } int sum=0; for(int i=0;i<l;i++) { for(int j=i+1;j<l;j++) { if(Across(v[i],v[j])) sum++; } } sum+=(l-1) + 1; printf("%d\n",sum); } return 0;}
- FZU 1015 土地划分
- fzu 1015 土地划分
- FZU 1015 土地划分
- FZU 1015 土地划分
- FZU 1015 土地划分
- FZU 1015 土地划分
- FZU 1015 土地划分
- fzu acm 1015 土地划分
- [刷题笔记] FZU 1015 土地划分
- fzu acm 1015 土地划分 (线段相交)
- Problem 1015 土地划分
- 计算几何 ( 判断线段相交 )——土地划分( FZU 1015 )
- FZU 1015 土地划分(判断两条直线是否相交)
- FZU 1015 土地划分 (计算几何求线段交点个数)
- BZOJ 3511: 土地划分
- 【u217】土地划分
- BZOJ3511 土地划分
- 土地划分 解题报告
- 1014. Waiting in Line (30)-PAT
- PAT_1015: Reversible Primes
- hdu 1195 BFS
- seo追求质量 不要刻意的去求数量
- libev 与libevent比较
- FZU 1015 土地划分
- HDU 1241 Oil Deposits
- 简单的Java IO操作 修改文件名称
- PHP高效率写法(详解原因)
- 黑马程序员----java之内部类
- 完全卸载oracle11g步骤
- c历史
- LEMON的特殊声明符的应用场景及用途总结
- 动态二维数组的分配和释放