历届试题 剪格子

/*
历届试题 剪格子  

问题描述

如下图所示,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

*/
import java.util.Scanner;
import java.util.Stack;

public class Main {
    static int m, n;
    static int map[][];
    static int data[][];
    static int sum = 0, sum1 = 0;
    static int visted[];
    static int min = Integer.MAX_VALUE;
    static Stack<Integer> road = new Stack<Integer>();

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        m = sc.nextInt();
        n = sc.nextInt();
        visted = new int[m * n];
        map = new int[m * n][m * n];
        data = new int[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                data[i][j] = sc.nextInt();
                sum1 += data[i][j];
            }
        }
        sc.close();
        creatMap();
        dfs(0);
        System.out.println(min);

    }

    static void vist(int k) {
        int i = k / m, j = k % m;
        sum += data[i][j];
        visted[k] = 1;
        road.push(k);
    }

    static void huisu(int k) {
        int i = k / m, j = k % m;
        sum -= data[i][j];
        visted[k] = 0;
        road.pop();
    }

    static boolean check() {
        int a[] = new int[m * n];
        for (int i = 0; i < a.length; i++)
            a[i] = visted[i];
        for (int i = 0; i < a.length; i++)
            if (a[i] == 0) {
                ddd(i, a);
                break;
            }

        if (flag)
            return true;
        return false;
    }

    static boolean flag = false;

    static boolean ddd_check(int a[]) {
        for (int i : a)
            if (i == 0) {

                return false;
            }
        return true;
    }

    static void ddd(int k, int a[]) {
        a[k] = 1;
        if (ddd_check(a))
            flag = true;
        for (int i = 0; i < m * n; i++) {
            if (map[k][i] == 1 && a[i] == 0) {
                ddd(i, a);
            }
        }
    }

    static void dfs(int k) {
        vist(k);
        if (sum == sum1 / 2 && check()) {
            if (min > road.size())
                min = road.size();
        }
        for (int i = 0; i < m * n; i++) {
            if (map[k][i] == 1 && visted[i] == 0) {
                dfs(i);
                huisu(i);
            }
        }
    }

    static void creatMap() {
        for (int i = 0; i < m * n; i++) {
            if (i - 1 >= 0 && i % m != 0)
                liantong(i, i - 1);
            if (i + 1 < m * n && (i + 1) % m != 0)
                liantong(i, i + 1);
            if (i + m < m * n)
                liantong(i, i + m);
            if (i - m >= 0)
                liantong(i, i - m);
        }
    }

    static void liantong(int i, int j) {
        map[i][j] = 1;
        map[j][i] = 1;
    }

}

 

posted @ 2018-03-22 14:43  忧伤的小毛驴  阅读(124)  评论(0编辑  收藏  举报