《算法图解》分而治之划分土地

目录

1.问题描述

2.问题分析

2.1基线条件

2.2问题分解

3.Python代码实现

4.总结


1.问题描述

如图所示,有一块长方形土地,假设长168,宽64,现在要将这块地均匀地分成方块,且分出的方块要尽可能大。

2.问题分析

使用分而治之的思想解决问题,包括两个步骤:
(1)找到基线条件,这种条件必须尽可能简单

(2)把问题不断分解,直到符合基线条件

2.1基线条件

对于把长方形分成正方形,且分出的正方形要尽可能大,需要以当前长方形的短边作为正方形的边长,不断往下划分。那划分到什么时候停止呢?我一开始想的是一直划分到剩下的长方形长和宽相等时停止,但这个条件并不是最大的基线条件。书中给出的基线条件是当长方形长边是短边的整数倍。仔细分析,可以发现,长宽相等是整数倍条件的一个特例,太过于简单,这样会增加递归的深度,导致堆栈占用过多。

2.2问题分解

在每一次划分的过程中,应该是对长边进行切割,分为短边的整数倍部分和剩余部分(有时候长边是短边的n倍,可以一次划分出n个正方形,如果此时一次只划分一个方块,会增加迭代次数)

3.Python代码实现

python代码如下所示

import math
from PIL import Image
from PIL import ImageDraw
square_width=[]


def division(length,width):
    remainder=length%width
    if remainder==0:
        multiple = int(math.floor(length / width))
        for i in range(multiple):
            square_width.append(width)
    else:
        multiple=int(math.floor(length/width))
        for i in range(multiple):
            square_width.append(width)
        remain=length-multiple*width
        length=width
        width=remain
        division(length,width)


if __name__=='__main__':
    length=168
    width=64
    division(length,width)
    print(u'划分的正方形边长:',square_width)
    im=Image.new('RGB',(length,width),'white')
    draw=ImageDraw.Draw(im)
    draw.line([(0,0),(length-1,0),(0,width-1),(length-1,width-1)],fill='black')

    #绘制划分后的土地
    x1=0
    x2=square_width[0]
    y1=0
    y2=square_width[0]
    draw.rectangle((x1,y1,x2,y2),fill='blue',outline='black')
    x1=square_width[0]
    x2=square_width[0]*2
    draw.rectangle((x1, y1, x2,y2), fill='blue',outline='black')
    x1=x2
    x2=square_width[2]+2*square_width[1]
    y2=square_width[2]
    draw.rectangle((x1, y1, x2, y2), fill='orange',outline='black')
    y1=y2
    y2=y1+square_width[3]
    x2=x1+square_width[3]
    draw.rectangle((x1, y1, x2, y2), fill='green',outline='black')
    x1=x2
    x2=x1+square_width[4]
    y2=y1+square_width[4]
    draw.rectangle((x1, y1, x2, y2), fill='red',outline='black')
    y1+=square_width[4]
    x2=x1+square_width[5]
    y2=y1+square_width[5]
    draw.rectangle((x1, y1, x2, y2), fill='purple',outline='black')
    x1=x2
    x2=x1+square_width[6]
    draw.rectangle((x1, y1, x2, y2), fill='purple',outline='black')
    im.save('../Algorithm_diagram/land_division.png')
    im.show()

如图所示,使用python实现了土地的划分

4.总结

(1)分而治之实际上是一种递归解决问题的方式,因此在选择基线条件时,简单的同时尽可能减少递归深度,如果深度过深,会占用大量的栈资源。

(2)分解问题时,每次递归应完成尽可能多的任务,不要作重复工作内容的递归。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值