题目 1432: [蓝桥杯][2013年第四届真题]剪格子
时间限制: 1Sec 内存限制: 128MB 提交: 2448 解决: 858
题目描述
历届试题 剪格子
时间限制: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
代码
思路一
def main():
m,n=map(int,input().strip().split())
map_=[]
for i in range(n):
map_.append(list(map(int,input().strip().split())))
all_sum=0
for i in range(n):
for j in range(m):
all_sum+=map_[i][j]
if all_sum%2!=0:
print(0)
return
visited=set()
temp_sum=0
res=[]
temp=[]
def helper(visited,row,col,temp_sum,temp):
'''
visited:记录已经遍历过的点
row:当前横坐标
col:当前纵坐标
temp_sum:已经遍历过的点的值的和
temp:储存了当前遍历的点的坐标
'''
if temp_sum==all_sum/2:
res.append(temp)
return
if temp_sum>all_sum/2:
return
if (row-1,col) not in visited and 0<=(row-1)<n and 0<=(col)<m:
helper(visited|{(row-1,col)},row-1,col,temp_sum+map_[row-1][col],temp+[(row-1,col)])
if (row+1,col) not in visited and 0<=(row+1)<n and 0<=(col)<m:
helper(visited|{(row+1,col)},row+1,col,temp_sum+map_[row+1][col],temp+[(row+1,col)])
if (row,col-1) not in visited and 0<=(row)<n and 0<=(col-1)<m:
helper(visited|{(row,col-1)},row,col-1,temp_sum+map_[row][col-1],temp+[(row,col-1)])
if (row,col+1) not in visited and 0<=(row)<n and 0<=(col+1)<m:
helper(visited|{(row,col+1)},row,col+1,temp_sum+map_[row][col+1],temp+[(row,col+1)])
# print(map_)
# print(map_[0][0])
helper(visited|{(0,0)},0,0,temp_sum+map_[0][0],temp+[(0,0)])
if not res:
print(0)
return
else:
print(len(min(res,key=len)))
return
main()
思路
- 从(0,0)这个点向四周遍历找到值等于总数字和一半的组合就记录到res中,最后从res中选出长度最小即包含的最小的格子数目。
def dfs(pair,num_now,sum_now):
global ret
global vis
if sum_now ==total//2 and num_now < ret:
ret = num_now
for i in dirc:
dx = pair[0] + i[0]
dy = pair[1] + i[1]
if 0<=dx<m and 0<=dy<n and not vis[dx][dy]:
vis[dx][dy]=True
#print(dx,dy,num_now,sum_now)
dfs((dx,dy),num_now+1,sum_now+lst[dx][dy])
vis[dx][dy]=False
n,m = map(int,input().split())
lst=[]
total,ret = 0,1000
for i in range(m):
tmp=list(map(int,input().split()))
lst.append(tmp)
total+=sum(tmp)
dirc=[(0,-1),(1,0),(-1,0),(0,1)]
vis=[[False for _ in range(n)]for _ in range(m)]
if total %2==1:
print(0)
else:
dfs((0,0),1,lst[0][0])
print(ret) if ret!=1000 else print(0)