2019年蓝桥杯练习3-楼号m和n之间的最短移动距离
[问题描述]
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
分析:
/*
找规律知:最短移动距离为两点横坐标差的绝对值+纵坐标差的绝对值。
奇数行:从小到大
偶数行:从大到小
*/
#include<stdio.h>
#include<math.h>
int row(int w,int i) { //计算点的行号
int irow; //下列计算取第一行的行号为1,而不是0
if(i%w==0) //值是宽度的倍数
irow=i/w;
else //值不是宽度的倍数
irow=i/w+1;
return irow;
}
int col(int w,int j) { //计算点的列号
int jcol; //下列计算取第一列的列号为1,而不是0
if(row(w,j)%2==0) { //该值在偶数行
if(j%w==0) // 找规律可知,偶数行能被整除肯定在第一列
jcol=1;
else //在偶数行(从大到小)但不能被整除,在倒数第j%w列,即正数第w-j%w+1列
jcol=w-j%w+1;
} else { //在奇数行
if(j%w==0) //找规律可知,偶数行能被整除肯定在最后一列
jcol=w;
else //在奇数行(从小到大)但不能被整除,在第j%w列
jcol=j%w;
}
return jcol;
}
int main()
{
int w,m,n;
while(scanf("%d %d %d",&w,&m,&n)==3) {
int s=fabs(row(w,n)-row(w,m))+fabs(col(w,n)-col(w,m));
printf("%d\n",s);
}
return 0;
}
分析:
可以不用想得太复杂,直接找规律,重点是找到计算行号和列号的规律,多验证几组边缘的数据来确定规律是否正确。