【计算几何】地主 pascal 解题报告

【计算几何】地主

Time Limit:1000MS  Memory Limit:65536K
Total Submit:24 Accepted:22

Description

地主(landlord.pas/c/cpp)

【问题描述】

    在Dukeswood这块土地上生活着一个富有的农庄主和他的几个孩子。在他临终时,他想把他的土地分给他的孩子。他有许多农场,每个农场都是一块矩形土地。他在农场地图上划上一些直线将矩形分成若干块。当他划直线时,他总是从矩形边界上的某一点划到另一个矩形边界上的点,这条线的结束点将成为下一条线的起始点。他划线时从不会让任三线共点。例如图1是某一种划分结果。


【计算几何】地主 <wbr>pascal <wbr>解题报告


    划分的起始点和结束点均以五角星标记。当他完成划分后,他想要数一下划出的土地的块数以确保每个孩子都有一块地。例如,图1中土地被划分成18块。然而这个庄主由于年迈常会数错,因而他寻求你的帮助。请写一个程序,输入原来的土地尺寸及线段的位置,输出划分出的土地块数。

Input

输入文件有多组数据组成。每组数据格式如下:
第一行输入地图的宽度w (1≤ w ≤1000)和高度 h (1 h 1000),均为整数。
第二行输入线段数L (1≤ L ≤50)。
以下L+1行每行一个整数坐标(Xi,Yi),庄主划的线段为(Xi,Yi)-(Xi+1,Yi+1),i=1,2,…,L。当然(Xi,Yi)必定在矩形的边界上。
最后一组数据w=h=0,标志文件结束,不需要处理。

Output

对于给定的输入,输出一行仅含一个数,即划分出的土地块数。

Sample Input

18 12
8
2 0
6 12
10 0
18 9
15 12
0 6
14 0
10 12
0 9
7 6
6
2 0
5 6
7 3
0 3
3 0
3 6
0 5
0 0

Sample Output

18
11

Source

 

题目看起来挺复杂的。

其实就是不断的枚举。

每增加一条线,就一定会多划分出一块地。

这跳线每穿过一条前面画的线,又会多划分出一块地。

 

 

var

 w,h,l,tot,i,j:longint;

 a:array[1..51,1..2]of longint;

 

function max(x,y:longint):longint;

begin

 if x>y then exit(x)

        else exit(y);

end;

 

function min(x,y:longint):longint;

begin

 if x<y then exit(x)

        else exit(y);

end;

 

function pan(i,j:longint):boolean;

var

 f:array[1..4,1..2]of longint;

begin

 f[1]:=a[j-1];

 f[2]:=a[j];

 f[3]:=a[i-1];

 f[4]:=a[i];

 

 if max(f[1,1],f[2,1])<min(f[3,1],f[4,1]) then exit(false);

 if min(f[1,1],f[2,1])>max(f[3,1],f[4,1]) then exit(false);

 if max(f[1,2],f[2,2])<min(f[3,2],f[4,2]) then exit(false);

 if min(f[1,2],f[2,2])>max(f[3,2],f[4,2]) then exit(false);

 

 if ((f[1,1]-f[4,1])*(f[3,2]-f[4,2])-

     (f[1,2]-f[4,2])*(f[3,1]-f[4,1]))*

    ((f[2,1]-f[4,1])*(f[3,2]-f[4,2])-

     (f[2,2]-f[4,2])*(f[3,1]-f[4,1]))>0 then exit(false);

 

 if ((f[3,1]-f[1,1])*(f[2,2]-f[1,2])-

     (f[3,2]-f[1,2])*(f[2,1]-f[1,1]))*

    ((f[4,1]-f[1,1])*(f[2,2]-f[1,2])-

     (f[4,2]-f[1,2])*(f[2,1]-f[1,1]))>0 then exit(false);

 

 exit(true);

end;

 

begin

 while true do

  begin

   tot:=0;

   fillchar(a,sizeof(a),0);

 

   read(w,h);

   if (w=0)and(h=0) then exit;

   read(l);

   for i:=1 to l+1 do

    read(a[i,1],a[i,2]);

   tot:=l+1;

 

  for i:=4 to l+1 do

   for j:=2 to i-2 do

    if pan(i,j) then inc(tot);

  writeln(tot);

 end;

end.

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值