来源: 第六届蓝桥杯省赛C++B组
算法标签:模拟
题目简介
X星球居民小区的楼房全是一样的,并且按矩阵样式排列。
其楼房的编号为 1,2,3…
当排满一行时,从下一行相邻的楼往反方向排号。
比如:当小区排号宽度为 6 时,开始情形如下:
1 2 3 4 5 6
12 11 10 9 8 7
13 14 15 .....
我们的问题是:已知了两个楼号 m 和 n,需要求出它们之间的最短移动距离(不能斜线方向移动)。
输入格式
输入共一行,包含三个整数 w,m,n,w 为排号宽度,m,n 为待计算的楼号。
输出格式
输出一个整数,表示 m,n 两楼间最短移动距离。
数据范围
1≤w,m,n≤10000,
输入样例:
6 8 2
输出样例:
4
思路
这题主要是模拟居民楼,利用行列来解决问题。
已知了两个楼号 m 和 n,需要求出它们之间的最短移动距离(不能斜线方向移动)
即求曼哈顿距离 点a(x1,y1) b(x2,y2) ans=abs(x1-x2)+abs(y1-y2)
如果直接利用矩阵坐标计算 则脱离m,n的大小关系,计算即为常数级 o(1)
如果以正常矩阵表示 则有
1 2 3 4 5 //列
0 0 1 2 3 4
1 5 6 7 8 9
2 10 11 12 13 14
3 15 16 17 18 19
4 20 21 22 23 24
//行
则可得行号==(n||m)/实际每行长度
则可得列号==(n||m)%实际每行长度
又因为本题是蛇形走位
即 行号为奇数时 列号翻转
if(行号==奇数)列号==实际长度-当前行号
则可求出 ans=abs(x1-x2)+abs(y1-y2)
C++ 代码
#include<iostream>
using namespace std;
int main()
{
int w,n,m;
cin>>w>>n>>m;
n--,m--;//从零计数 否则有边界问题
int x1,x2,y1,y2;//x行 y列
x1=n/w,x2=m/w,y1=n%w,y2=m%w;
if(x1%2)y1=w-1-y1;//行号为奇数时翻转
if(x2%2)y2=w-1-y2;
cout<<abs(x1-x2)+abs(y1-y2);//曼哈顿距离
return 0;
}