算法 — 蛇形填数暴解

题目描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

如下图所示,小明用从 1 开始的正整数“蛇形”填充无限大的矩阵。

1 2 6 7 15 ...

3 5 8 14 ...

4 9 13 ...

10 12 ...

11 ...

...

容易看出矩阵第二行第二列中的数是 5。请你计算矩阵中第 20 行第 20 列的数是多少?

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 128M

解题思路:

该题可以通过一个暴力解法进行求解,也可以通过规律进行求解。规律求解在我的另一篇博文里面,感兴趣的读者可以去我的主页里面找。至于暴力求解,首先我们需要知道,对于第 20 行 第 20 列的数值,我们需要建立一个多大的数组才可以存储到该位置。对于第二个位置存储的数值 5,我们可以观察,这是第二行,下标为 1,此时需要的数组是一个三行三列的数组,也就是说需要 1 + 1 + 1 的行数 (列数自然和行数相等,也是3),这其中的第一个 1 就是数值 5 所在行的以上行数,第二个 1 是数值5 所在行占一行,第三个 1 是数值 5 下面的行数要和上面的行数相等。同样,对于存储第三个对角线数值 13 来说需要的行数是 2 + 1 + 2,也就是一个行数和列数都是 5 的矩阵。可能有的同学说这里只需要行列数都为 3 就可以了呀,为啥还需要行列数为 5 的呢?这里就是我们解体过程的一个需要,我们是对角线位置数值的对角线列上的每一个元素都要存储到数组中的。

        首先,我们需要建立一个行列数都为 40 的数组,然后通过算法将该数组进行填充,可以看到这个数组分为两种斜列,一种是斜向右上角的,一种是斜向左下角的 (如下图),这两类可以将填充数组的时候分为两类,一类是斜向上 (开始的时候 j = 0,后来随着向上,i 逐渐减小,j 逐渐增大),另一种是斜向下的 (开始的时候i = 0,后来随着向下,j 逐渐减小,i 逐渐增大,和斜向上正好相反)。故可以通过一个循环对整体进行把握 (循环 40 次),然后每一次循环都判断是斜向上还是斜向下的 (判断当前次数取余 2 是否等于 1),之后再进行一次小的循环对该斜列的位置进行数值填充,这里比较需要注意的地方是行 i 和列 j 的控制,除此之外就没有难点了,该算法的 Java 代码实现如下:

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        int[][] arr = new int[40][40];
        int i, j, k, sum = 1;
        for (k = 0; k < 40; k++) {
          if (k % 2 == 1) {//判断是向上类型还是向下类型,这是向下
            for (i = 0, j = k - i; i <= k; i++, j--) {
              arr[i][j] = sum;
              sum++;
            }
          }else {//这是向上
            for (j = 0, i = k - j; j <= k; j++, i--) {
              arr[i][j] = sum;
              sum++;
            }
          }
        }
        System.out.println(arr[19][19]);
    }
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值