【洛谷 P8623】[蓝桥杯 2015 省 B] 移动距离 题解(数学)

[蓝桥杯 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是小区排号的宽度,mn是两个楼号。

然后,计算出mn在二维平面上的坐标。x1x2是横坐标,y1y2是纵坐标。这里使用了取余数和整除的操作来计算坐标,并使用了ceilDiv函数来进行向上取整的除法。

然后,检查y1y2的奇偶性是否不同。如果不同,就把x2调整为w + 1 - x2。这是因为楼号在相邻两行上的方向是相反的,所以需要做这个调整。

最后,输出x2x1的绝对差加上y2y1的绝对差,这就是mn两楼间的最短移动距离。


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;
}
  • 25
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值