第四届蓝桥杯专科组预赛



标题:剪格子

    如图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

import java.util.Scanner;
public class Test10 {
static int minCount = Integer.MAX_VALUE;
static int[][] value;     //存用户输入的值
static int[][] state;     //标记被剪下来的值
static int sum2 = 0; //所有值的一半
static int sum3 = 0; //被剪下来值的和
static int count2 = 0;   //被剪下来的格子个数
static int n = 0;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int b = in.nextInt();
int a = in.nextInt();
value = new int[a][b];
state = new int[a][b];
for (int i = 0; i < a; i++)
for (int j = 0; j < b; j++){
value[i][j] = in.nextInt();
sum2 += value[i][j];
}
if(sum2%2!=0){
System.out.println(0);
return;
}
sum2 = sum2 / 2;
System.out.println("-------------start-------------");
long l = System.currentTimeMillis();
dfs(0, 0);
System.out.println(minCount);
System.out.println(System.currentTimeMillis()-l+"ms");
}



public static void dfs(int x, int y) {
if (x < 0 || x >= value.length || y < 0 || y >= value[0].length
|| state[x][y] == 1)
return;
state[x][y] = 1; // 剪
count2++;
sum3 += value[x][y];
// 检查剪下的一部分,能和另外一部分数子和相等不
if(check()){
state[x][y] = 0;
sum3 -= value[x][y];
count2--;
return;
}
dfs(x - 1, y);
dfs(x + 1, y);
dfs(x, y - 1);
dfs(x, y + 1);
state[x][y] = 0; // 还原
sum3 -= value[x][y];
count2--;
}

public static boolean check() {
if(sum3>sum2)
return true;
if(sum2==sum3){
if (count2 < minCount) {// 如果剪的包含左上角格子
//if(isConn()){
minCount = count2;
//}
}
return true;
}
return false;
}
}




汗,当时怎么没想到。。。

你可能感兴趣的:(第四届蓝桥杯专科组预赛)