package s4;
import java.text.BreakIterator;
import java.util.Scanner;
public class test10 {
public static void main(String[] args) {
// TODO Auto-generated method stub
/*
* 标题:剪格子 如图p1.jpg所示,3 x 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 再例如: 用户输入: 4 3 1 1 1 1 1
* 30 80 2 1 1 1 100 则程序输出: 10 (参见p2.jpg) 资源约定: 峰值内存消耗(含虚拟机) < 64M CPU消耗
* < 5000ms 请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
* 所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。 注意:不要使用package语句。不要使用jdk1.6及以上版本的特性。
* 注意:主类的名字必须是:Main,否则按无效代码处理。
*/
Scanner scan = new Scanner(System.in);
int b = scan.nextInt();
int a = scan.nextInt();
int[][] s = new int[a][b];
for (int i = 0; i < a; i++) {
for (int j = 0; j < b; j++) {
s[i][j] = scan.nextInt();
}
}
int sum = 0;
int sum1 = 0;
int[][] s1 = new int[a][b];
for (int i = 0; i < a; i++) {
for (int j = 0; j < b; j++) {
s1[i][j] = 0;
sum1 += s[i][j];
}
}
s1[0][0] = 1;
if (sum1 % 2 == 0) {
// System.out.println(1);
f(0, 0, a, b, s, s[0][0], sum1, s1, 1);
} else {
// System.out.println(1);
}
}
public static void f(int x, int y, int a, int b, int s[][], int sum,
int sum1, int s1[][], int bu) {
// System.out.println(sum);
if (sum > sum1 / 2) {
s1[x][y] = 0;
return;
}
if (sum == sum1 / 2) {
System.out.println(bu);
return;
} else {
// 左
if (y - 1 >= 0)
if (s1[x][y - 1] == 0) {
s1[x][y - 1] = 1;
f(x, y - 1, a, b, s, sum + s[x][y - 1], sum1, s1, bu + 1);
}
// 右
if (y + 1 < b)
if (s1[x][y + 1] == 0) {
s1[x][y + 1] = 1;
f(x, y + 1, a, b, s, sum + s[x][y + 1], sum1, s1, bu + 1);
}
// 上
if (x - 1 >= 0)
if (s1[x - 1][y] == 0) {
s1[x - 1][y] = 1;
f(x - 1, y, a, b, s, sum + s[x - 1][y], sum1, s1, bu + 1);
}
// 下
if (x + 1 < a)
if (s1[x + 1][y] == 0) {
s1[x + 1][y] = 1;
f(x + 1, y, a, b, s, sum + s[x + 1][y], sum1, s1, bu + 1);
}
s1[x][y] = 0;
// return;
}
}
}
import java.text.BreakIterator;
import java.util.Scanner;
public class test10 {
public static void main(String[] args) {
// TODO Auto-generated method stub
/*
* 标题:剪格子 如图p1.jpg所示,3 x 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 再例如: 用户输入: 4 3 1 1 1 1 1
* 30 80 2 1 1 1 100 则程序输出: 10 (参见p2.jpg) 资源约定: 峰值内存消耗(含虚拟机) < 64M CPU消耗
* < 5000ms 请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
* 所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。 注意:不要使用package语句。不要使用jdk1.6及以上版本的特性。
* 注意:主类的名字必须是:Main,否则按无效代码处理。
*/
Scanner scan = new Scanner(System.in);
int b = scan.nextInt();
int a = scan.nextInt();
int[][] s = new int[a][b];
for (int i = 0; i < a; i++) {
for (int j = 0; j < b; j++) {
s[i][j] = scan.nextInt();
}
}
int sum = 0;
int sum1 = 0;
int[][] s1 = new int[a][b];
for (int i = 0; i < a; i++) {
for (int j = 0; j < b; j++) {
s1[i][j] = 0;
sum1 += s[i][j];
}
}
s1[0][0] = 1;
if (sum1 % 2 == 0) {
// System.out.println(1);
f(0, 0, a, b, s, s[0][0], sum1, s1, 1);
} else {
// System.out.println(1);
}
}
public static void f(int x, int y, int a, int b, int s[][], int sum,
int sum1, int s1[][], int bu) {
// System.out.println(sum);
if (sum > sum1 / 2) {
s1[x][y] = 0;
return;
}
if (sum == sum1 / 2) {
System.out.println(bu);
return;
} else {
// 左
if (y - 1 >= 0)
if (s1[x][y - 1] == 0) {
s1[x][y - 1] = 1;
f(x, y - 1, a, b, s, sum + s[x][y - 1], sum1, s1, bu + 1);
}
// 右
if (y + 1 < b)
if (s1[x][y + 1] == 0) {
s1[x][y + 1] = 1;
f(x, y + 1, a, b, s, sum + s[x][y + 1], sum1, s1, bu + 1);
}
// 上
if (x - 1 >= 0)
if (s1[x - 1][y] == 0) {
s1[x - 1][y] = 1;
f(x - 1, y, a, b, s, sum + s[x - 1][y], sum1, s1, bu + 1);
}
// 下
if (x + 1 < a)
if (s1[x + 1][y] == 0) {
s1[x + 1][y] = 1;
f(x + 1, y, a, b, s, sum + s[x + 1][y], sum1, s1, bu + 1);
}
s1[x][y] = 0;
// return;
}
}
}