NO2---蓝桥杯java---剪格子---dfs

如下图所示,3×33×3 的格子中填写了一些整数。

NO2---蓝桥杯java---剪格子---dfs_第1张图片

我们沿着图中的红色线剪开,得到两个部分,每个部分的数字和都是 6060。

本题的要求就是请你编程判定:对给定的 m×n的格子中的整数,是否可以分割为两个连通的部分,使得这两个区域的数字和相等。

如果存在多种解答,请输出包含左上角格子的那个区域包含的格子的最小数目。

如果无法分割,则输出 00。

NO2---蓝桥杯java---剪格子---dfs_第2张图片

输入格式

第一行包含两个整数 m,n,表示表格的宽度和高度。

接下来是 n行,每行 m个正整数,用空格分开。

输出格式

在所有解中,包含左上角的分割区可能包含的最小的格子数目。

如果无法分割,则输出 00。

数据范围

1≤n,m<10,
格子内的数均在1到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
关于这道题 在acwing中跑不出来 结果不对
但在蓝桥杯官网平台可以出来
总的来说就是把c 语言的dfs 改成 java 版本的
标准dfs+判断返回(经过格子总值==总格之和/2)
所以dfs的题重点是找出怎么判断返回

import java.util.Scanner;

public class Main {
    static int n;
    static int m;
    static int sum;
    static int N=20;
    static int []dx={0,0,1,-1};
    static int []dy={1,-1,0,0};
    static int ans;
     static int[][] val;
     static boolean[][] st;
     
 	public static void main(String[] args) {
 	    sum=0;
		Scanner sc=new Scanner(System.in);
		n=sc.nextInt();
		m=sc.nextInt();
		val=new int[n+1][m+1];
		st=new boolean[n+1][m+1];
		ans=Integer.MIN_VALUE;
		for(int i=1;i<=n;i++) {
			for(int j=1;j<=m;j++) {
			val[i][j]=sc.nextInt();
			sum+=val[i][j];
			}
		}
		sc.close();
		
		if(sum%2==0) {
			st[1][1]=true;
			dfs(1,1,1,val[1][1]);
		}
		if(ans==Integer.MIN_VALUE)ans=0;
		System.out.println(ans);
		
		
		

	}
 	
    public static void dfs(int x,int y,int cnt,int v) {//当前x y 坐标//步数//走过格值相和
    
    	if(v==sum/2) {//到底了
    		ans=ans>cnt?ans:cnt;
    		
    		return;
    	}
    	if(v>sum/2)return;//违规
    	for(int i=0;i<4;i++) {
    		int a=x+dx[i];
    		int b=y+dy[i];
    		if(a<1||b<1||a>n||b>m)continue;//出界
    		if(st[a][b]==true)continue;//已走过
    		st[a][b]=true;
    		dfs(a,b,cnt+1,v+val[a][b]);
    		st[a][b]=false;//回溯
    	}
    }



}

加油,冲冲冲

你可能感兴趣的:(蓝桥杯,深度优先,算法)