【蓝桥杯】试题 历届试题 剪格子(python解法+java解法)
资源限制
时间限制: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。
输出格式
输出一个整数,表示在所有解中,包含左上角的分割区可能包含的最小的格子数目。
样例输入1
3 3
10 1 52
20 30 1
1 2 3
样例输出1
3
样例输入2
4 3
1 1 1 1
1 30 80 2
1 1 1 100
样例输出2
10
python解法:
# 100分
def dfs(x, y, sum1, num):
global count #不定义全局变量,函数里面的变量不影响外边,而且函数不能调用外边的变量,相当于两个变量了。
global flag #在函数外边声明的变量,在函数里边是不能直接用的,正如上面所说,他们属于两个不同的变量了。
if sum1==sum2:
count=num
flag=True
return
if sum1>sum2:
return
used[x][y]=1 #列表可以直接在函数内部改变外部的全局变量
# 如果现在不是最后一行,那么可以往下走
if x+1<n and used[x+1][y]==0:
dfs(x+1,y,sum1+list1[x][y],num+1)
# 如果现在不是最顶上的一行,那么可以往上走
if x-1>=0 and used[x-1][y]==0:
dfs(x-1,y,sum1+list1[x][y],num+1)
# 如果现在不是最右边的一列,那么可以往右边走
if y+1<m and used[x][y+1]==0:
dfs(x,y+1,sum1+list1[x][y],num+1)
# 如果现在不是最左边的一列,那么可以往左边走
if y-1>=0 and used[x][y-1]==0:
dfs(x,y-1,sum1+list1[x][y],num+1)
# 执行到这说明s[i][j]这个数字不行,还原为未使用状态
used[x][y]=0 # 搜索失败,回溯,将访问记录清零
m,n=map(eval,input().split())
list1=[]
for i in range(n):
list1.append((list(map(eval,input().split()))))
# 标记每个格子的使用情况:0-未使用;1-已使用
used=[[0 for i in range(m)] for j in range(n)]
sum1=0
sum2=0
for i in range(n):
for j in range(m):
sum2+=list1[i][j]
sum2/=2
count=0
flag=False
dfs(0, 0, 0, 0)
if flag:
print(count)
else:
print(0)
java解法:
// 100分
import java.util.Scanner;
public class Main {
private static int m,n;
private static String[] str;
private static int[][] arr1; //输入数组
private static int[][] used; //每个数组元素是否被使用
private static int sum1=0; //所有格子中数字的总和
private static int count=0; //包含左上角的分割区可能包含的最小的格子数目
private static boolean isFlag=false;
public static void main(String[] args){
Scanner scan=new Scanner(System.in);
m= scan.nextInt();
n= scan.nextInt();
/*
m、n在一行输入,
例:4 3 ;
在两行输入,
例:
4
3
都可以被读取
*/
arr1=new int[n][m]; //一定不能忘记初始化,否则报错
scan.nextLine();
for(int i=0;i<n;i++){
str=scan.nextLine().split(" ");
for(int j=0;j<m;j++){
arr1[i][j]=Integer.parseInt(str[j]);
sum1+=arr1[i][j];
}
}
// System.out.println(Arrays.deepToString(arr1));
used=new int[n][m]; //一定不能忘记初始化,否则报错
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
used[i][j]=0;
}
}
// used[0][0]=1;
dfs(0,0,0,0);
if(isFlag){
System.out.println(count);
}else{
System.out.println(0);
}
}
public static void dfs(int x,int y,int sum2,int num){
// System.out.println(sum2);
if(sum2==sum1/2){
// System.out.println("qq");
isFlag=true;
count=num;
return;
}
if(sum2>sum1/2){
return;
}
used[x][y]=1;
if(x-1>=0 && used[x-1][y]==0){
dfs(x-1,y,sum2+arr1[x][y],num+1);
}
if(x+1<n && used[x+1][y]==0){
dfs(x+1,y,sum2+arr1[x][y],num+1);
}
if(y-1>=0 && used[x][y-1]==0){
dfs(x,y-1,sum2+arr1[x][y],num+1);
}
if(y+1<m && used[x][y+1]==0){
dfs(x,y+1,sum2+arr1[x][y],num+1);
}
used[x][y]=0; //搜索失败,回溯,将访问记录清零
}
}