实验目的
1. 了解分治策略算法思想及基本原理;
2. 掌握使用分治算法求解问题的一般特征;
3. 掌握分解、治理的方法;
4. 能够针对实际问题,能够正确的分解、治理,设计分治算法;
5. 能够正确分析算法的时间复杂度和空间复杂度。
二、实验任务
下列2个问题中任选一个完成
1、棋盘覆盖问题:给定一个2k×2k的棋盘(具体图例见教材),有一个特殊棋格,拥有一个特殊棋格的棋盘称为特殊棋盘。现要用四种L型骨牌(具体图例见教材)覆盖特殊棋盘上除特殊棋格外的全部棋格,不能重叠,找出覆盖方案。
2、邮局选址问题:对一个以XY轴表达的城市里,n个居民点散乱分布,居民点位置可以用坐标(x,y)表示,任意两点(x1,y1)(x2,y2)间距离可以用| x1-x1|+|y1-y2|度量,居民希望在城市中选择建立邮局的最佳位置,使得n个居民点到邮局的距离综合最小
三、审题结果
学生撰写内容
四、问题建模结果
给定n 个居民点的位置,编程计算n 个居民点到邮局的距离总和的最小值。
输入由多组测试数据组成。
每组测试数据输入的第1 行是居民点数n,1≤n≤10000。接下来n 行是居民点的位置,每行2 个整数x 和y,-10000≤x,y≤10000。
因为街区中任意2 点(x1,y1)和(x2,y2)之间的距离可以用数值 |x1-x2 |+ |y1-y2 |度量;
那么:
邮局的x坐标只与n个居民点的x坐标相关;
邮局的y 坐标只与n个居民点的y坐标相关;
以求x坐标为例
假设对n个居民点的x坐标按大小排序后为x1,x2......xn;
对x1,xn两点来说,最近的点肯定在x1,xn之间,且跟两点的距离和==xn-x1;
对x2,x(n-1)两点来说,最近的点肯定在x2,x(n-1)之间,且跟两点的距离和==x(n-1)-x2;
....
所以若n为奇数,则邮局的x坐标取最中间的值时最小;
所以若n为偶数,则邮局的x坐标可以取最中间两个值的之间的任意值;
最终公式:x=(x(n/2+1)+x(n/2+2)+...+xn)-(x1+x2+..+x(n/2))
五、算法实现部分
覆盖问题
# 开发时间:2024-03-20 14:01
def chessBoard(tr, tc, dr, dc, size):
if size == 1:
return
global tile
global board
tile += 1
t = tile
s = size // 2
if dr < tr + s and dc < tc + s:
chessBoard(tr, tc, dr, dc, s)
else:
board[tr + s - 1][tc + s - 1] = t
chessBoard(tr, tc, tr + s - 1, tc + s - 1, s)
if dr < tr + s and dc >= tc + s:
chessBoard(tr, tc + s, dr, dc, s)
else:
board[tr + s - 1][tc + s] = t
chessBoard(tr, tc + s, tr + s - 1, tc + s, s)
if dr >= tr + s and dc < tc + s:
chessBoard(tr + s, tc, dr, dc, s)
else:
board[tr + s][tc + s - 1] = t
chessBoard(tr + s, tc, tr + s, tc + s - 1, s)
if dr >= tr + s and dc >= tc + s:
chessBoard(tr + s, tc + s, dr, dc, s)
else:
board[tr + s][tc + s] = t
chessBoard(tr + s, tc + s, tr + s, tc + s, s)
def show_chess(board):
n = len(board)
for i in range(n):
for j in range(n):
print(board[i][j], end=" ")
print('')
tile = 0
size = int(input())
n = pow(2, size)
if __name__ == '__main__':
dr, dc = map(int, input().split())
board = [[0 for x in range(n)] for y in range(n)]
board[dr - 1][dc - 1] = -1
chessBoard(0, 0, dr - 1, dc - 1, n)
show_chess(board)
2、邮局选址问题:
n = int(input())
lx = []
ly = []
for i in range(n):
x, y = map(int, input().split())
lx.append(x)
ly.append(y)
lx = sorted(lx) # 排序
ly = sorted(ly)
if n % 2 != 0: # 奇数,求中位数
z = int((n - 1) / 2)
x0 = lx[z]
y0 = ly[z]
else: # 偶数
z = int(n / 2)
x0 = int((lx[z] + lx[z - 1]) / 2)
y0 = int((ly[z] + ly[z - 1]) / 2) # 题目要int
sumx = 0
sumy = 0
for j in lx:
p = abs(x0 - j)
sumx = sumx + p
for k in ly:
q = abs(y0 - k)
sumy = sumy + q
print(sumx + sumy)
六、实验结果分析
学生撰写内容
七、实验总结
学生撰写内容