[蓝桥杯 2015 省 B] 移动距离
题目描述
X 星球居民小区的楼房全是一样的,并且按矩阵样式排列。其楼房的编号为 $1,2,3, \cdots $ 。
当排满一行时,从下一行相邻的楼往反方向排号。
比如:当小区排号宽度为 6 6 6 时,开始情形如下:
1 2 3 4 5 6
12 11 10 9 8 7
13 14 15 .....
我们的问题是:已知了两个楼号 m m m 和 n n n,需要求出它们之间的最短移动距离。(不能斜线方向移动)
输入格式
输入为 3 3 3 个整数 w , m , n w,m,n w,m,n,空格分开,都在 1 1 1 到 10000 10000 10000 范围内。
w w w 为排号宽度, m , n m,n m,n 为待计算的楼号。
输出格式
要求输出一个整数,表示 m m m 与 n n n 两楼间最短移动距离。
样例 #1
样例输入 #1
6 8 2
样例输出 #1
4
样例 #2
样例输入 #2
4 7 20
样例输出 #2
5
提示
时限 1 秒, 256M。
蓝桥杯 2015 年省赛 B 组 H 题。
思路
整个算法的主要思路就是将楼号转化为二维平面上的坐标,然后计算两点之间的距离。将这个问题转化为在二维平面上的点到点的距离问题。
首先定义一个辅助函数ceilDiv
,用于实现向上取整的除法操作。
读取了三个输入参数:w
是小区排号的宽度,m
和n
是两个楼号。
然后,计算出m
和n
在二维平面上的坐标。x1
和x2
是横坐标,y1
和y2
是纵坐标。这里使用了取余数和整除的操作来计算坐标,并使用了ceilDiv
函数来进行向上取整的除法。
然后,检查y1
和y2
的奇偶性是否不同。如果不同,就把x2
调整为w + 1 - x2
。这是因为楼号在相邻两行上的方向是相反的,所以需要做这个调整。
最后,输出x2
和x1
的绝对差加上y2
和y1
的绝对差,这就是m
和n
两楼间的最短移动距离。
AC代码
#include <algorithm>
#include <iostream>
#define mp make_pair
#define AUTHOR "HEX9CF"
using namespace std;
using ll = long long;
const int N = 1e6 + 7;
const int INF = 0x3f3f3f3f;
const ll MOD = 1e9 + 7;
int ceilDiv(int a, int b) { return (a + b - 1) / b; }
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int w, m, n;
int x1, x2, y1, y2;
cin >> w >> m >> n;
x1 = m % w;
x2 = n % w;
y1 = ceilDiv(m, w);
y2 = ceilDiv(n, w);
if (y1 % 2 != y2 % 2) {
// y1和y2奇偶性不同
x2 = w + 1 - x2;
}
// cout << x1 << " " << y1 << endl;
// cout << x2 << " " << y2 << endl;
cout << abs(x2 - x1) + abs(y2 - y1) << "\n";
return 0;
}