编程语言
首页 > 编程语言> > 蓝桥杯-剪格子(python实现)

蓝桥杯-剪格子(python实现)

作者:互联网

蓝桥杯-剪格子(python实现)

一、题目描述

时间限制:1.0s 内存限制:256.0MB

如下图所示,3 x 3 的格子中填写了一些整数。
±—*---±-+
|10* 1|52|
±-****–+
|20|30* 1|
*******–+
| 1| 2| 3|
±-±-±-+
  我们沿着图中的星号线剪开,得到两个部分,每个部分的数字和都是60。

  本题的要求就是请你编程判定:对给定的m x n 的格子中的整数,是否可以分割为两个部分,使得这两个区域的数字和相等。
如果存在多种解答,请输出包含左上角格子的那个区域包含的格子的最小数目。

  如果无法分割,则输出 0。

输入:
程序先读入两个整数 m n 用空格分割 (m,n< 10)。
表示表格的宽度和高度。
接下来是n行,每行m个正整数,用空格分开。每个整数不大于10000。
输出:
输出一个整数,表示在所有解中,包含左上角的分割区可能包含的最小的格子数目。
样例输入

3 3
10 1 52
20 30 1
1 2 3

样例输出

3

二、解题思路:

  主要思路是用深度优先搜索的方式搜索解空间,具体实现可以看注释。
(在解决许多问题时采用深度优先而不是宽度优先的原因有很多,如深度优先可以利用递归编写程序,代码更简单易懂;深度优先在搜索中可以剪枝;深度优先在搜索最优解时,可以将代价大于已知最优解的分支剪枝…)



"""h,w分别代表即将加入解的表中结点的第一、二个索引,
    res是加入结点前当前左上角区域已包含的格子数,
    cur是加入结点前左上角区域的和"""
def dfs(h, w, res, cur):
    global m, n, ls, sum1, best, used
    # 将结点加入左上角区域
    cur = cur+ls[h][w]
    res += 1
    used[h][w]=1
    if res<best:
        if cur == sum1:
            best = res
        elif cur< sum1:
            if h<n-1 and used[h+1][w]==0:
                dfs(h+1, w, res, cur)
            if h>0 and used[h-1][w]==0:
                dfs(h-1, w, res, cur)
            if w<m-1 and used[h][w+1]==0:
                dfs(h, w+1, res, cur)
            if w>0 and used[h][w-1]==0:
                dfs(h, w-1, res, cur)
    # 让结点还原未考虑状态
    used[h][w]=0
        
        
    


"""m,n接收输入,ls保存表格,used全局变量表示结点是否添加过,0未添加,1添加过
    best用于保存搜索到的左上角最少格子数"""
# while True:
m, n = map(int, input().split())
ls = list()
for i in range(n):
    ls.append(list(map(int, input().split())))
sum1 = sum(map(sum, ls))
# 若不能整除2则一定不存在解,若能整除则左上角区域和为sum1=sum1/2
if sum1%2!=0:
    print(0)
else:
    sum1 = sum1//2
best = 100
used = [[0 for i in range(m)] for i in range(n)]
dfs(0, 0, 0, 0)
if best<100:
    print(best)
else:
    print(0)

标签:used,cur,格子,python,sum1,蓝桥,ls,左上角
来源: https://blog.csdn.net/qq_47780707/article/details/122400880