【Luogu】 P3665 [USACO17OPEN] Switch Grass P
发布人:shili8
发布时间:2025-02-23 15:39
阅读次数:0
**Switch Grass**
**Problem Description**
在一个 $n times n$ 的草地上,存在一些牛。每只牛都有一个初始位置,并且可以移动到相邻的格子中(即水平或垂直方向)。现在,我们需要将所有牛都移到某个目标位置。
我们可以使用以下操作来实现这一点:
* 将一头牛从当前位置移动到相邻的格子中。
* 将一头牛从当前位置移动到目标位置。
每次移动都会花费 $1$ 个单位的时间。请问,所有牛都移到目标位置所需的最少时间是多少?
**Input Format**
* 第一行:两个整数$n$和$m$,分别表示草地的大小和牛的数量。
* 每个牛的初始位置(从 $1$ 到 $n^2$)。
**Output Format**
*一个整数,表示所有牛都移到目标位置所需的最少时间。
**Sample Input**
531413
**Sample Output**
6
**Explanation**
在这个例子中,我们有 $n =5$ 和 $m =3$。初始位置为 $(1,1)$、$(2,4)$ 和 $(3,3)$。
我们可以将所有牛都移到目标位置所需的最少时间表示为 $d_1 + d_2 + ldots + d_m$,其中 $d_i$ 是第 $i$ 头牛从初始位置移动到目标位置所需的距离。
在这个例子中,我们可以将所有牛都移到目标位置所需的最少时间表示为 $3 +4 +2 =9$。但是,这个答案是错误的,因为我们需要考虑到每次移动都会花费 $1$ 个单位的时间。
因此,正确的答案应该是 $d_1 + d_2 + ldots + d_m - (n-1) =3 +4 +2 -4 =5$。
**Code**
cpp#include <iostream> #include <vector> using namespace std; const int N =1000000; int n, m, ans[N]; void solve() { cin >> n >> m; for (int i =1; i <= m; ++i) { int x, y; cin >> x >> y; ans[x + n * (y -1)]++; } for (int i =0; i < N; ++i) if (ans[i] >0) cout << i % n +1 << " "; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int T =1; while (T--) { solve(); cout << " "; } return0; }
**Explanation**
在这个代码中,我们首先读入草地的大小 $n$ 和牛的数量 $m$。然后,我们为每头牛读入初始位置。
我们使用一个数组 `ans` 来存储从每个格子移动到目标位置所需的距离。对于每头牛,我们将其初始位置转换为一个数字,表示该格子的坐标,然后将该数字加 $1$ 到 $n^2$,以得到一个数字,表示该格子在草地中的位置。
我们然后检查 `ans` 数组中是否有任何值大于 $0$。如果有,我们就输出这些值所对应的格子的坐标。
**Time Complexity**
时间复杂度为 O(n^2)。
**Space Complexity**
空间复杂度为 O(n^2)。