当前位置:实例文章 » 其他实例» [文章]【Luogu】 P3665 [USACO17OPEN] Switch Grass P

【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)。

其他信息

其他资源

Top