Codeforces Round 863 (Div. 3) B. Conveyor Belts

发布时间 2023-10-20 17:50:14作者: zsxuan

给一个 \(n \times n\) 的矩阵, \(n\) 是偶数。将矩阵按圈分割,同一圈的位置可以不消耗代价移动,可以消耗一个代价移动到相邻圈。

给出 \(n, x_1, y_1, x_2, y_2\) ,询问 \((x_1, y_1)\) 移动到 \((x_2, y_2)\) 的代价最小是多少。

显然对每个圈可以选择左上角作为定点。

  • 显然直线 \(f(i) = n - j\) 左侧的点 \((a, b)\) 可以直接定位到定点 \(min(a, b)\) 。这些点满足 \(a + b \leq 1 + n\)
  • 直线 \(f(i) = n - j\) 右侧的点 \((a, b)\) 经过 \((\frac{n}{2},\frac{n}{2})\) 中心对称后还在同一圈,且可以移到左侧。

假设 \((x_1', y_1'), (x_2', y_2')\) 都是调整过的点,则答案为 \(|min(x_1', y_1') - min(x_1', y_1')|\)

view
#include <bits/stdc++.h>
typedef long long ll;
void solve(){
	int n, x_1, y_1, x_2, y_2; std::cin >> n >> x_1 >> y_1 >> x_2 >> y_2;
	if (x_1 + y_1 > n + 1) x_1 = n + 1 - x_1, y_1 = n + 1 - y_1;
	if (x_2 + y_2 > n + 1) x_2 = n + 1 - x_2, y_2 = n + 1 - y_2;
	std::cout << abs(std::min(x_1, y_1) - std::min(x_2, y_2)) << '\n';
}               
int main() { 
	int _ = 1; std::cin >> _;
	while (_--) solve();
	return 0;
}