#P1452. 2023.08.13-第一题-米小游的棋盘
-
1000ms
Tried: 398
Accepted: 159
Difficulty: 3
所属公司 :
米哈游
时间 :2023年8月13日
-
算法标签>模拟
2023.08.13-第一题-米小游的棋盘
思路:模拟
考虑两个点 (a,b) 到 (c,d) 的距离。
实际上,x 轴的移动和 y 轴的移动是独立的,所以我们单独考虑每个轴。
在 x 轴上,从 a 到 c 有两种方式:
-
第一种是直接到达,即 a 到达 c ,移动距离为 abs(a−c) 。
-
第二种是通过边缘到达
如果 a<c ,则先从 a 到 1 ,再从 1 到 n ,再从 n 到 c ,移动距离为 (a−1+1+n−c=n+a−c)
如果 a>c ,则先从 a 到 n ,再从 n 到 1 ,再从 1 到 c ,移动距离为 (n−a+1+c−1=n+c−a)
而这两者可以概括为 n−abs(a−c)
对于 y 轴是一样的。
所以两个点之间的移动距离为:
$\min(abs(a-c),n-abs(a-c))+\min(abs(b-d),m-abs(b-d))$
代码
C++
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
int main()
{
int n, m;
cin >> n >> m;
PII a, b, c;
cin >> a.first >> a.second;
cin >> b.first >> b.second;
cin >> c.first >> c.second;
long long ans = 0;
// 从 a 到 b 的 x 轴
ans += min(abs(a.first - b.first), n - abs(a.first - b.first));
// 从 a 到 b 的 y 轴
ans += min(abs(a.second - b.second), m - abs(a.second - b.second));
// 从 b 到 c 的 x 轴
ans += min(abs(b.first - c.first), n - abs(b.first - c.first));
// 从 b 到 c 的 y 轴
ans += min(abs(b.second - c.second), m - abs(b.second - c.second));
cout << ans << "\n";
return 0;
}
python
n, m = map(int, input().split())
points = []
for _ in range(3):
x, y = map(int, input().split())
points.append((x, y))
ans = 0
# 从 a 到 b 的 x 轴
ans += min(abs(points[0][0] - points[1][0]), n - abs(points[0][0] - points[1][0]))
# 从 a 到 b 的 y 轴
ans += min(abs(points[0][1] - points[1][1]), m - abs(points[0][1] - points[1][1]))
# 从 b 到 c 的 x 轴
ans += min(abs(points[1][0] - points[2][0]), n - abs(points[1][0] - points[2][0]))
# 从 b 到 c 的 y 轴
ans += min(abs(points[1][1] - points[2][1]), m - abs(points[1][1] - points[2][1]))
print(ans)
Java
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int m = scanner.nextInt();
int[][] points = new int[3][2];
for (int i = 0; i < 3; i++) {
points[i][0] = scanner.nextInt();
points[i][1] = scanner.nextInt();
}
long ans = 0;
// 从 a 到 b 的 x 轴
ans += Math.min(Math.abs(points[0][0] - points[1][0]), n - Math.abs(points[0][0] - points[1][0]));
// 从 a 到 b 的 y 轴
ans += Math.min(Math.abs(points[0][1] - points[1][1]), m - Math.abs(points[0][1] - points[1][1]));
// 从 b 到 c 的 x 轴
ans += Math.min(Math.abs(points[1][0] - points[2][0]), n - Math.abs(points[1][0] - points[2][0]));
// 从 b 到 c 的 y 轴
ans += Math.min(Math.abs(points[1][1] - points[2][1]), m - Math.abs(points[1][1] - points[2][1]));
System.out.println(ans);
}
}
题目内容
米小游有一个 n×m 的棋盘,一次移动可以选择上下左右四个方向移动一次,不同于普通棋盘,这个棋盘是循环的。
即 (x,m) 和 (x,1) 两个点可以一步到达,其中 1≤x≤n 。同样的, (n,y) 和 (1,y) 两个点也可以一步到达,其中 1≤y≤m 。
现在米小游需要从 A 点先走到 B 点,再从 B 点走到 C 点,问最小移动次数是多少。
输入描述
第一行两个整数,n 和 m 。 接下来三行,第一行是点 A 的坐标 (xA,yA),第二行是点 B 的坐标 (xB,yB) ,第三行是点 C 的坐标 (xC,yC)。
$1\leq n,m\leq 10^9, 1\leq x_A,x_B,x_C\leq n, 1\leq y_A,y_B,y_C\leq m$
输出描述
输出从 A 到 B ,再从 B 到 C 的最小移动次数。
样例
输入
4 4
1 2
1 3
1 4
输出
2