蓝桥杯(C/C++组)2015-8 移动距离

题目描述
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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值