Cut lattice (deep search)

Problem Description

As shown in the image below, the 3 x 3 grid is filled with some integers.
+–*–+–+
|10* 1|52|
+– ** –+
|20|30* 1|
* –+
| 1| 2| 3|
+–+–+–+

We cut along the asterisk line in the diagram to get two parts, each of which sums to 60.

The requirement of this question is to ask you to program to determine whether the integer in the given mxn grid can be divided into two parts, so that the sum of the numbers in these two areas is equal.

If there are multiple solutions, output the minimum number of cells contained in the area containing the upper left cell.

If it cannot be split, 0 is output.
input format

The program first reads two integers mn separated by spaces (m, n<10).

Indicates the width and height of the table.

Next are n lines, each with m positive integers, separated by spaces. Each integer is not greater than 10000.
Output Format
Outputs an integer representing the smallest possible number of cells in the partition containing the upper left corner of all solutions.
Sample Input 1
3 3
10 1 52
20 30 1
1 2 3
Sample Output 1
3
Sample Input 2
4 3
1 1 1 1
1 30 80 2
1 1 1 100
Sample Output 2
10

Solution:
The code is as follows:

import java.util.Scanner;

/** 
 * @author 作者 : Cactus
 * @version 创建时间:2018-3-26 下午09:34:10 
 */
public class Main {
    private static int[][] arr,visited; // arr用于记录每个位置的数值,visited用于做标记
    private static int m , n, num = 0, sum = 0, count = 0, ans = Integer.MAX_VALUE;
    //m 行, n 列, num 用于即时记录当前路径的数字和, count 用于记录当前路径内格子数目, ans 记录最优路径的格子数 
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();//列
        m = sc.nextInt();//行
        arr = new int[m][n];
        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
                arr[i][j] = sc.nextInt();
                sum += arr[i][j];
            }
        }
        sc.close();
        visited = new int[m][n];
        if(sum % 2 != 0){
            System.out.println(0);
        }else{
            sum = sum / 2;
            dfs(0,0); //从左上角第一个元素出发,保证(0,0)在每一条路径内。
            System.out.println(ans);
        }

    }
    private static void dfs(int x, int y){
        count++;
        visited[x][y] = 1;
        num += arr[x][y];
        if(num == sum && ans > count){
            ans = count; //若找到某一条路径,其和为总和的一半, 与上一条路径相比,选取最优解。
        }else{ //深搜遍历每一种情况
            if(x > 0 && visited[x - 1][y] == 0 && num + arr[x - 1][y] <= sum){
                dfs(x - 1, y);
            }
            if(y > 0 && visited[x][y - 1] == 0 && num + arr[x][y - 1] <= sum){
                dfs(x, y - 1);
            }
            if(x < m -1 && visited[x + 1][y] == 0 && num + arr[x + 1][y] <= sum){
                dfs(x + 1, y);
            }
            if(y < n - 1 && visited[x][y + 1] == 0 && num + arr[x][y + 1] <= sum){
                dfs(x, y + 1);
            }
        }
        visited[x][y] = 0; //归位,回溯
        num -= arr[x][y];
        count--;
    }
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325518622&siteId=291194637
cut
Recommended