JAVA算法练习(7):剪格子

这是一个关于编程算法的博客,主要讨论如何使用动态规划解决一个二维格子分割的问题。给定一个m x n的格子,里面填有整数,目标是判断是否能将其分割成两个部分,使得两个区域的数字和相等。如果可以,找到包含左上角格子的最小格子数。博客中提供了详细的解题思路,包括准备工作、定义变量、递归方法实现及边界条件判断,并给出了具体的Java代码实现。
摘要由CSDN通过智能技术生成

------文章底部代码分享

 一、题目

标题:剪格子
如图所示, 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

 

 

资源约定:
峰值内存消耗(含虚拟机) < 64M
CPU消耗 <5000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入..”的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.6及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。

二、解题

2.1

        准备工作:

        1.定义两个确定行列的全局变量;

        2.定义一个整型全局的二位数组,一个跟该数组行列相同的布尔型二位数组;

        3.定义一个计算总数的变量;

        4. main 方法内将他们初始化;

        (将变量定义到全局进行不同方法的使用时更加方便)

 2.2

        定义一个存储格子数量的变量;

        编写一个方法,方法内传四个值,分别是行列坐标、格子数量、所选取格子内数的总和;

 2.3

        利用动态规划将坐标可以移动的方向都进行递归;

        counts 每次将使用的格子上的数据累加起来;

        布尔型数组进行同位置上的布尔值改变用于让后面算法确定是否使用过当前坐标,方法调用完毕后要记得对布尔值的回溯;

 2.4

        方法内进行两个返回判断:

        第一个返回判断是判断当前调用是否满足两部分区域同等条件,以及当前的格子数量是不是最少情况下的,如果满足这两个条件就将格子数记录并返回;

        第二个返回判断是用于判断坐标是否越界、格子内数据总量是否越界以及当前坐标是否已经遍历过,如果是则返回;

 2.5

        最后进行输出,题目要求是没有满足条件就输出 0 ,故判断如果记录值被改变了就输出新值,未被改变就输出 0 ;

三、代码分享

import java.util.Scanner;

public class Main{
        static int m , n , nums ;
        static int[][] array ;
        static boolean[][] bool;
        static int countNum = Integer.MAX_VALUE ;
    public static void main( String[] args) {
        Scanner sc = new Scanner( System.in );
        m = sc.nextInt();
        n = sc.nextInt();
        array = new int[n][m];
        bool = new boolean[n][m];
        for( int i = 0 ; i < n ; i++ )
            for( int j = 0 ; j < m ; j++ ) {
                array[i][j] = sc.nextInt();
                nums += array[i][j];
            }
        
        int times = 0;
        count(  0 , 0 , times ,0 );
        if ( countNum != Integer.MAX_VALUE )
            System.out.println( countNum );
        else System.out.println( 0 );
    }

    public static void count( int x , int y , int times , int counts) {
        if ( counts == nums * 0.5 && countNum > times ){
                countNum = times ;
            return;
        }
        if( x == n || x < 0 || y == m || y < 0 || counts > nums * 0.5 || bool[x][y] != false ) {
            return;
        }
            counts += array[x][y];
            bool[x][y] = true;
            count(  x - 1 , y , times + 1 , counts );
            count(  x + 1 , y , times + 1 , counts );
            count(  x , y + 1 , times + 1 , counts );
            count(  x , y - 1 , times + 1 , counts );
            bool[x][y] = false;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jc_caterpillar

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值