剪格子 java_【每日蓝桥】10、一三年省赛Java组真题"剪格子" | 程序员灯塔

你好呀,我是灰小猿,一个超会写bug的程序猿!

欢迎大家关注我的专栏“每日蓝桥”,该专栏的主要作用是和大家分享近几年蓝桥杯省赛及决赛等真题,解析其中存在的算法思想、数据结构等内容,帮助大家学习到更多的知识和技术!

标题:剪格子

如图p1.jpg所示,3 x 3的格子中填写了一些整数

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

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

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

程序输入输出格式要求:

程序先读入两个整数m n 用空格分割(m,n<10)

表示表格的宽度和高度

接下来是n行,每行m个正整数,用空格分开,每个整数不大于10000

程序输出:在所有解中,包含左上角的分割区可能包含的最小的格子数目

如无法分割,则输出0

例如:

用户输入:

3 3

10 1 52

20 30 1

1 2 3

7bf61ee03ccd3254ac831fea2de3127e.png

则程序输出:

3

再例如:

用户输入:

4 3

1 1 1 1

1 30 80 2

1 1 1 100

bf13435515589f8e8c6b782b089e8e41.png

则程序输出:

10

资源约定:

峰值内存消耗 < 64M

CPU消耗 < 1000ms

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

所有代码都放在同一个源文件中,测试通过后,拷贝提交该源码。

注意:main函数需要返回0

注意:只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数

注意:所有依赖的函数必须明确的在源文件中,#include 不能通过工程设置而忽略常用头文件

提交时,注意选择所期望的编译器类型

解题思路:

本题应该按照数据结构中树的结构进行查找,从左上角的第一个格子开始对周围的格子进行深度遍历,直到找到格子中数值和等于总数值和的一半时,记录此时的格子数,最后根据比较找出格子数最少的方法。

答案源码:

package 一三年省赛真题;

import java.util.Scanner;

public class Year2013_t10 {

static int[][] g;

static int[][] sign;

static int m;

static int n;

static int s=0;//记录格子中元素的总和

static int answer = Integer.MAX_VALUE;//最终格子数

public static void main(String[] args) {

Scanner scanner = new Scanner(System.in);

m = scanner.nextInt();//输入格子的宽

n = scanner.nextInt();//输入格子的高

g = new int[n][m];

sign = new int[n][m];

for (int i = 0; i < n; i++) {

for (int j = 0; j < m; j++) {

g[i][j] = scanner.nextInt();//为格子赋值

s+=g[i][j];

}

}

move(0, 0, 0, 0);

System.out.println(answer);

}

/**

* 记录格子的遍历过程

* @param i 移动的横坐标

* @param j 移动的纵坐标

* @param step 步数

* @param sum 格子中元素的总和

* */

public static void move(int i,int j,int step,int sum) {

//如果该格子坐标不在范围内,或该格子已经走过,则返回

if (i==n||i<0||j<0||j==m||sign[i][j]==1) {

return;

}

// 如果当前数值和是总和的一半

if (sum*2==s) {

answer = Math.min(answer, step);//对格子数(步数)与符合要求的格子数比较,取出最小值

}

sign[i][j] = 1;//对走过的格子进行标记,表示格子已经走过

move(i+1, j, step+1, sum+g[i][j]);//down

move(i-1, j, step+1, sum+g[i][j]);//up

move(i, j-1, step+1, sum+g[i][j]);//left

move(i, j+1, step+1, sum+g[i][j]);//right

sign[i][j] = 0;//将该格子重新置于未走过的状态(回溯算法)

}

}

输出样例:

edbc87325a301a0320030e7d42cc4bca.png

其中有不足或者改进的地方,还希望小伙伴留言提出,一起学习!

感兴趣的小伙伴可以关注专栏!

灰小猿陪你一起进步!

最后,我正在参加2020年度博客之星的评选,求小伙伴们帮忙投票支持一下哟!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值