题目描述
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范围内
w为排号宽度,m,n为待计算的楼号。
输出
要求输出一个整数,表示m n 两楼间最短移动距离。
样例输入 Copy
6 8 2
样例输出 Copy
4
问题分析:
首先判断m和n的行数,w为每行楼的个数
设m0,n0分别为m的行数和n的行数
则有
m0 = m/w + 1;
n0 = n/w +1;
注意
行数算法当m = q*w时,不用加一,即m0 = m/w
设最短距离为s
因为不能有斜线,所以最短距离为折线,例如
1 2 3 4 5 6
12 11 10 9 8 7
13 14 15 …
当m=8,n = 2时,最短距离为2-3-4-5-8;
可以得知 s 等于纵向距离与横向距离之和。
而纵向距离为|m0-n0|,
设横向距离为s1,
判断m、n为奇数排还是偶数排分情况讨论
设m、n在第一排对应的楼号数分别为m1、n1
在第二排对应的楼号分别为m2、n2
(1)当m为奇数排,n为奇数排时。
m1 = m%w,n1 = n%w
即s1 = |m1-n1|
(2)当m为偶数排,n为偶数排时
m2 = m%w,n2 = n%w
即s1 = |m2-n2|
(3)当m为偶数排,n为奇数排时
m对应第二排的位置m2,m2 = m-(m0-2)*w;
m对应第一排的位置m1,m1 =2*w+1-m2 ;
n对应第一排的位置,n1 = n%w;
即s1 =|m1-n1|
(4)当m为奇数排,n为偶数排时
n对应第二排的位置n2,n2 = n-(n0-2)*w;
n对应第一排的位置n1,n1 =2*w+1-n2 ;
m对应第一排的位置 m1 = m%w;
s = s1+|m0-n0|
综上
当m为奇数排时 m1 = m%w
为偶数排时,m1 = 2*w+1-m+(m0-2)*w
n同理
注意 当m或n为奇数排最后一个时 m1 = w
下面是c++代码
#include<iostream>
using namespace std;
#include<math.h>
int main()
{
int w = 0;//排号宽度
int m = 0;
int n = 0;
cin>>w>>m>>n;
int m0 = 0;//m号楼的排数
int n0 = 0;//n号楼的排数
if(m%w==0)
{
m0 = m/w;
}
else
{
m0 = m/w + 1;
}
if(n%w==0)
{
n0 = n/w;
}
else
{
n0 = n/w + 1;
}
int s = 0;//最短距离
int s0 = 0;//两楼的纵向最短距离
int s1 = 0;//两楼的横向最短距离
s0 = abs(m0-n0);
int m1 = 0;//m号楼对应在第一排的楼号
int n1 = 0;//n号楼对应在第一排的楼号
if(m0%2==1)
{
if(m%w==0)
{
m1 = w;
}
else
{
m1 = m%w;
}
}
else
{
m1 = 2*w+1-m+(m0-2)*w;
}
if(n0%2==1)
{
if(n%w==0)
{
n1 = w;
}
else
{
n1 = n%w;
}
}
else
{
n1 = 2*w+1-n+(n0-2)*w;
}
s1 = abs(m1-n1);
s = s0+s1;
cout<<s;
return 0;
}