蓝桥杯算法题-X星球居民小区的楼房全是一样的,并且按矩阵样式排列。
题目描述
[问题描述]
X星球居民小区的楼房全是一样的,并且按矩阵样式排列。其楼房的编号为1,2,3… 当排满一行时,从下一行相邻的楼往反方向排号。 比如:当小区排号宽度为6时,开始情形如下:
1 2 3 4 5 6
12 11 10 9 8 7
13 14 15 …
我们的问题是:已知了两个楼号m和n,需要求出它们之间的最短移动距离(不能斜线方向移动)
输入为3个整数w m n,空格分开,都在1到10000范围内
要求输出一个整数,表示m n 两楼间最短移动距离。
[样例输入]
6 8 2
[样例输出]
4
[样例输入]
4 7 20
[样例输出]
5
实现思路
前几天,看到了这道题,我的思路是这样的,可以用一个二维数组来存储,求最短的距离,其实就是求m和n的坐标,两个坐标相减后相加就是最短的距离。所以问题的关键就是求m和n的二维坐标。
这里需要考虑的是,m或者n前面有偶数行还是奇数行。如果是偶数行的话,m或者n的纵坐标,就需要将与width取余后的整数从左边列(第0列)开始算起,反之,如果是奇数行的话,取余后的结果就要从最右边列(第width-1列)开始算起。
举个例子,以width为6,m为2,n为8来求解最短距离。
- 8除6的结果为1,也即8的横坐标(数组从0开始的),即前面是奇数行,8与6取余的结果是2,因为前面是奇数行,所以从右边开始算起,就是用width来减余数,就是6减去2,结果为4。所以8的二维坐标就是[1,4]。
- 2除6的结果为0,也即2的横坐标,2除6的余数为2,因为2的前面是偶数行,所以纵坐标需要从左边开始算起,所以2的二维坐标就是[0,1](数组纵列是从0开始)。
- 当然,还需要考虑一种比较特殊的情况,就是width的倍数,例如width为6,12,18,…这类数。它能够整除width,12除6的结果是2,这样就认为它前面就是有两行,但是实际上它的前面只有一行。所以还需要对这一种情况进行判断。这种情况只有两种,就是要么它的纵坐标为0,要么就是width-1。这种情况的判断可以在上面是奇数行还是偶数行的判断里边再加一个判断。如果余数为0,则需要根据是偶数行还是奇数行,把列数对应置为0和width-1。下面是用java实现的代码。
public static int getMiniDistance(int width, int start, int end) {int temp = 0;//交换start和end,保证end要大于startif (start > end) {temp = start;start = end;end = temp;}//row_end是end前面有多少行(后面为了减少变量命名,直接用这个来作为end的横坐标),col_end是end与width取余的余数(后面也是作为了end的列坐标)// 同理,row_start和col_start也一样。int row_end = end / width, col_end = end % width, row_start = start / width, col_start = start % width;//如果end前面有偶数行if (row_end % 2 == 0) {//并且余数为0,说明这个数能被整除的,则这个数行数需要减1,列数置为0if (col_end == 0) {row_end -= 1;}//如果不能被整除,说明是每行除去两端的数。前面是偶数行的,需要从左边开始算起,需要注意的是数组的行和列从0开始,所以需要将余数减1。else {col_end -= 1;}}//如果前面为奇数行else {//并且余数为0,说明这个数位于最右边,则行数需要减1,列数col_end置为width-1。if (col_end == 0) {row_end -= 1;col_end = width - 1;}//否则的话,则列数需要从右边开始算起,width减去col就是列数。else {col_end = width - col_end;}}//start也是同样的处理方式,如果start前面有偶数行if (row_start % 2 == 0) {//并且余数为0,说明这个数能被整除的,则这个数的列数为0,则需要行数减1,if (col_start == 0) {row_start -= 1;}//如果不能被整除,说明是每行除去两端的数。前面是偶数行的,需要从左边开始算起,else {col_start -= 1;}}//如果前面为奇数行else {//并且余数为0,说明这个数位于最右边,则行数需要减1,col_end为width-1。if (col_start == 0) {row_start -= 1;col_start = width - 1;}//否则的话,就按照普通的数来处理。else {col_start = width - col_start;}}System.out.println(start + "的坐标为:[" + row_start + "," + col_start + "]");System.out.println(end + "的坐标为:[" + row_end + "," + col_end + "]");return (row_end - row_start) + (Math.abs(col_end - col_start));}
最后返回结果时,需要考虑有可能end的列坐标要小于start的,所以用了绝对值。
上面的代码看起来有点臃肿,因为end和start的if判断一样,所以可以考虑用方法来封装。下面是封装之后的代码。
public static int getMiniDistance(int width, int start, int end) {int temp = 0;//交换start和end,保证end要大于startif (start > end) {temp = start;start = end;end = temp;}//row_end是end前面有多少行(后面为了减少变量命名,直接用这个来作为end的横坐标),col_end是end与width取余的余数(后面也是作为了end的列坐标)// 同理,row_start和col_start也一样。int row_end = end / width, col_end = end % width, row_start = start / width, col_start = start % width;int result_end[] = getRowAndCol(width, row_end, col_end), result_start[] = getRowAndCol(width, row_start,col_start);row_end = result_end[0];col_end = result_end[1];row_start = result_start[0];col_start = result_start[1];System.out.println(start + "的坐标为:[" + row_start + "," + col_start + "]");System.out.println(end + "的坐标为:[" + row_end + "," + col_end + "]");return (row_end - row_start) + (Math.abs(col_end - col_start));}public static int[] getRowAndCol(int width, int row, int col) {int result[] = new int[2];//如果end前面有偶数行if (row % 2 == 0) {//并且余数为0,说明这个数能被整除的,则这个数行数需要减1,列数置为0if (col == 0) {row -= 1;}//如果不能被整除,说明是每行除去两端的数。前面是偶数行的,需要从左边开始算起,需要注意的是数组的行和列从0开始,所以需要将余数减1。else {col -= 1;}}//如果前面为奇数行else {//并且余数为0,说明这个数位于最右边,则行数需要减1,列数col_end置为width-1。if (col == 0) {row -= 1;col = width - 1;}//否则的话,则列数需要从右边开始算起,width减去col就是列数。else {col = width - col;}}result[0] = row;result[1] = col;return result;}
用方法封装之后,看起来就清晰了很多。
运行结果
public static void main(String[] args) {System.out.println("最短距离为" + getMiniDistance(6, 8, 2));System.out.println("最短距离为" + getMiniDistance(4, 7, 20));}
总结
- 这题的思路其实不算难,就是我自己实现起来的话,费点时间。
- 这个实现也是我自己的想法,肯定有比我更优的实现,这里只是记录一下我自己的想法,因为自己之前对算法是有点恐惧的,认为自己做不出来。事实上,只要去积极思考,多下功夫,还是可以做出来的。
- 通过这道题也算是给自己的一个鼓舞吧,也给其他做这道题的小伙伴一个思路。
- 路漫漫其修远兮,吾将上下而求索。大家一起加油哈。
蓝桥杯算法题-X星球居民小区的楼房全是一样的,并且按矩阵样式排列。相关推荐
- X星球居民小区的楼房全是一样的...
每周一题之3 [问题描述] X星球居民小区的楼房全是一样的,并且按矩阵样式排列.其楼房的编号为1,2,3... 当排满一行时,从下一行相邻的楼往反方向排号. 比如:当小区排号宽度为6时,开始情形如下: ...
- 【蓝桥杯算法题】用java遍写税收计算
[蓝桥杯算法题]用java遍写税收计算 题目:劳务报酬税收计算:输入 m ,输出税后收入.如果 m <=800,不扣税, 如果800< m <=4000.则 m 减去800后的金额扣 ...
- 【蓝桥杯算法题】获取桌面图标名称和坐标
[蓝桥杯算法题]获取桌面图标名称和坐标 实现 解释 实现 可以使用Python的第三方库pyautogui来获取桌面图标的名称和坐标.下面是一个示例代码: import pyautogui# 获取屏幕 ...
- CSDN蓝桥杯算法题——题解Java版本——切面条
目录 题目:切面条 答案目标: 推导过程: 解析过程: 对照Java编码1: 对照Java编码2: 总结: 题目:切面条 一根高筋拉面,中间切一刀,可以得到2根面条. 如果先对折1次,中间切一刀,可以 ...
- Python蓝桥杯算法题--从入门到精通 30天强化实训 |CSDN独创
[编程入门]温度转换 输入一个华氏温度,要求输出摄氏温度.公式为 c=5(F-32)/9,取位2小数. 一个华氏温度,浮点数 F=float(input()) c=(5*(F-32)/9) c=&qu ...
- 备战蓝桥杯-枚举、排序、模拟专项练习详解(含有多道蓝桥杯原题)
枚举.模拟与排序 蓝桥杯所有专项练习 蓝桥杯原题: 连号区间数 小明这些天一直在思考这样一个奇怪而有趣的问题: 在 1∼N1∼N 的某个排列中有多少个连号区间呢? 这里所说的连号区间的定义是: 如果区 ...
- 第六届蓝桥杯真题总结
第六届蓝桥杯真题总结 第一题:奖券数目 有些人很迷信数字,比如带"4"的数字,认为和"死"谐音,就觉得不吉利.虽然这些说法纯属无稽之谈,但有时还要迎合大众的需求 ...
- 蓝桥杯python省赛冲刺篇2——常用算法的详细解析及对应蓝桥杯真题:打表模拟法、递推递归法、枚举法、贪心算法、差分与前缀和
注意:加了题目链接 目录 注意:加了题目链接 一.打表模拟法 介绍 1. 算式问题 题目描述 解析与代码演示 2. 求值 题目描述 解析与代码演示 3. 既约分数 题目描述 解析与代码演示 4. 天干 ...
- c语言oj题1923偶数之和,问题 1923: [蓝桥杯][算法提高VIP]学霸的迷宫 (BFS)
题目描述 学霸抢走了大家的作业,班长为了帮同学们找回作业,决定去找学霸决斗.但学霸为了不要别人打扰,住在一个城堡里,城堡外面是一个二维的格子迷宫,要进城堡必须得先通过迷宫.因为班长还有妹子要陪,磨刀不 ...
- 【C/C++】蓝桥杯算法必刷题(三)目标ICPC铜/蓝桥杯国一
目录 前言 题解文章汇总 题目传送门:算法必刷题(三) 该题单中第一类考点:二进制 1018.有趣的二进制 1019.[NOIP2006]数列 1020.只能吃土豆的牛牛 该题单中第二类考点:思维 1 ...
最新文章
- Eclipse CDT中EOF输入的解决方法
- RESET MASTER 和RESET SLAVE 命令的使用方法 注意事项
- ubuntu的sudo输入密码时光标不动的问题
- 为什么APF框架初始化时有两个一模一样的analyticConfiguration请求
- bzoj4152-[AMPPZ2014]The_Captain
- latex的基本使用
- #ifndef HeaderName_h #define HeaderName_h #endif 使用详解
- python 调用mysql存储过程返回结果集
- django+echarts数据可视化(NBA球队数据可视化02)!
- TU-768与IT180A对比分析报告
- BlueCoat ProxySG配置FTP代理
- CentOS7安装 SGE
- vue中使用tsx语法
- Lead-follower因子:新闻共现股票收益的关联性研究
- javamail调用阿里企业邮箱实现推送包括多个附件
- 更新again:微机原理与汇编语言-练习题
- Mac下手动安装Tex/Latex Package
- js 对象的解构赋值
- identifier of an instance was altered from XXXX to XXXX解决
- 64位系统上使用PLSQL Developer的解决方案