题目:
八卦阵相传是诸葛亮创设的一种战斗队形和兵力部署,由八种阵势组成。为了方便,采用矩阵描述一个八卦阵,它由八个单阵组成,,每个单阵由多个兵力区域组成一种阵势,如图所示,其中数字为一个兵力区域的士兵个数。假设单阵与单阵之间兵力区域不会相邻,且单阵中兵力区域至少存在一个兵力相邻区域(注:相邻是指再其↖、正上、↗、正右、↘、正下、↙、正左八个方位与其相邻),请用最快的速度计算出八个单阵中的兵力(士兵个数)的最大值和最小值。
输入:
一个二维矩阵,对应着的是元素的值是行和列的大小 以及每个点的士兵的个数。
思路:
根据题意,一个阵中八个单阵,要计算的是八个单阵中最大和最小值。一定要先简化,并明确问题。
那么只需要计算每个单阵的士兵数量即可。
这里有几个关键点:
- 单阵个数的统计
- 单阵士兵的计算
重点:构造合适的数据结构
详细解释:
对于上下左右分别定义一些操作,模拟移动。
对于单阵,其实质就是一个多路的树,只不过有些分支不符合要求。模拟树的搜索即可找到一个单阵中所有的有效的点。
对于寻找所有的阵型,可以直接遍历一下,寻找即可,根据题意共有八个,所以只要找到八个属于单阵中的点,通过单阵中的点进行单阵搜索,题目的解!
代码:
# coding=utf8
__author__ = 'lfc'
from queue import Queue
# 定义操作,八个方向
op = {
"u": lambda i, j: (i - 1, j),
"u_r": lambda i, j: (i - 1, j + 1),
"r": lambda i, j: (i, j + 1),
"d_r": lambda i, j: (i + 1, j + 1),
"d": lambda i, j: (i + 1, j),
"d_l": lambda i, j: (i + 1, j - 1),
"l": lambda i, j: (i, j - 1),
"u_l": lambda i, j: (i - 1, j - 1),
}
# 八个阵型
graphs = {
"0": set(),
"1": set(),
"2": set(),
"3": set(),
"4": set(),
"5": set(),
"6": set(),
"7": set(),
}
# 检验点的合法性
def check(i, j, x, y, g_count, ri):
if i < 0 or i >= x or j < 0 or j >= y:
return False
if (i, j) in graphs[str(g_count)]:
return False
print i, j
if ri[i][j] == 0:
return False
return True
# 单个阵型的搜索
def single_search(i, j, x, y, g_count, ri):
g_count = str(g_count)
q = Queue(maxsize=x * y)
q.put((i, j))
while not q.empty():
i, j = q.get()
print "get", i, j
for k, v in op.items():
n_i, n_j = v(i, j)
if check(n_i, n_j, x, y, g_count, ri):
print "add", n_i, n_j
q.put((n_i, n_j))
graphs[g_count].add((n_i, n_j)) # 这个地方笔误写错成 n_j, n_j 注意
all_count = 0
for item_i, item_j in graphs[g_count]:
all_count += ri[item_i][item_j]
# print all_count, "-=" * 20
return all_count
# 当前点是否属于新的阵型
def is_single_graph(i, j):
for k, v in graphs.iteritems():
if (i, j) in v:
return False
return True
# 搜索所有的点,找到所有阵型,并求出最大,最小值
def all_search(x, y, ri):
g_count = 0
max_v = -0xffffff
min_v = 0xffffff
for i in range(x):
for j in range(y):
if ri[i][j] > 0 and is_single_graph(i, j):
current_count = single_search(i, j, x, y, g_count, ri)
g_count += 1
if current_count > max_v:
max_v = current_count
if current_count < min_v:
min_v = current_count
return max_v, min_v
# 测试数据
n = [[34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 30],
[0, 23, 10, 5, 5, 0, 0, 0, 5, 5, 5, 5, 5, 0, 0, 0, 30, 0, 40, 0],
[0, 9, 0, 0, 5, 0, 0, 0, 4, 4, 4, 4, 4, 0, 0, 0, 0, 30, 0, 0],
[0, 8, 7, 7, 0, 5, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 7, 0, 9, 0],
[0, 9, 0, 0, 5, 0, 5, 0, 0, 12, 12, 0, 0, 0, 0, 10, 0, 0, 0, 9],
[0, 0, 0, 0, 5, 0, 0, 5, 0, 12, 12, 0, 0, 5, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 12, 0, 0, 5, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0],
[40, 30, 3, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 10, 0],
[0, 0, 20, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 5, 6, 5, 10, 10, 0],
[40, 30, 3, 7, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 10, 0],
[0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 17, 0, 0, 6, 5, 7, 7, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 20, 0, 0, 7, 0, 0, 0, 0, 4, 4, 0, 0, 0, 0, 0, 10, 0, 0, 0],
[0, 20, 0, 0, 7, 0, 0, 0, 0, 4, 4, 0, 0, 0, 0, 0, 10, 0, 0, 0],
[0, 20, 0, 0, 7, 0, 0, 0, 0, 4, 4, 0, 0, 0, 0, 0, 10, 0, 0, 0],
[0, 30, 0, 7, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 10, 0, 50],
[0, 40, 7, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 50, 0],
[43, 30, 25, 10, 50, 0, 0, 0, 6, 6, 6, 6, 0, 0, 0, 0, 0, 50, 0, 0]]
print all_search(20, 20, n)
输出:
(323, 116)
另外,用python 写代码简洁,易懂!