Pixiv - KiraraShss
654 字
3 分钟
交替放置的玻璃杯题解
题目1: 交替放置的玻璃杯
有2n个玻璃杯挨个排成一排,前n个装满苏打水,其余n个杯子为空。交换杯子的位置,使之按照满—空—满—空的模式排列,而且杯子移动的次数要最少

这道题目不在力扣里哦,提示:用分治法求解。
题目理解

我们可以发现:
- 目标状态的下标存在规律
- 杯满为偶数,杯空为奇数
- 要达到目标状态,只需要交换绿色线连着的两个杯子
- 两端的杯子必定在正确的位置,从1和开始,每隔一个杯子就不在正确的位置
- 最少的交换次数为
Method 1 双指针
使用左右指针分别从两边向中间逼近,交换杯子
伪代码
1. 初始化l=1, r=2n-22. 不断循环交换杯子,记录交换次数,l+=2,r+=23. return 交换次数时空复杂度分析
-
时间复杂度:实际上两个指针相遇即可退出循环,循环次数为,所以时间复杂度为
-
空间复杂度:只需维护一个string数组,大小为,所以空间复杂度也为
代码
#include <bits/stdc++.h>using namespace std;const int N = 20010;string cups[N];// full的index应该为偶数,empty的index应该为奇数int n;int swap_cups(){ int res = 0; int l = 1, r = 2 * n - 2; while (l < n && r >= n) { swap(cups[l], cups[r]); l += 2, r -= 2; res ++ ; } return res;}int main(){ int res; cin >> n; for (int i = 0; i < n; i ++ ) cups[i] = "full"; for (int i = n; i < 2 * n; i ++ ) cups[i] = "empty";
res = swap_cups(); cout << res << endl; for (int i = 0; i < 2 * n; i ++ ) cout << cups[i] << " "; return 0;}Method 2 分治
base case
- n = 1时自动满足满-空
- n = 2时只需交换中间两个杯子
general

时空复杂度分析
- 时间复杂度:
- 空间复杂度:
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 20010;string cups[N];// full的index应该为偶数,empty的index应该为奇数
int n;
int swap_cups_divide(int l, int r){ if (l >= r) return 0;
swap(cups[l], cups[r]); return swap_cups_divide(l + 2, r - 2) + 1;}
int main(){ int res; cin >> n; for (int i = 0; i < n; i ++ ) cups[i] = "full"; for (int i = n; i < 2 * n; i ++ ) cups[i] = "empty";
res = swap_cups_divide(1, 2 * n - 2); cout << res << endl; for (int i = 0; i < 2 * n; i ++ ) cout << cups[i] << " "; return 0;}文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
交替放置的玻璃杯题解
https://printsdf.dpdns.org/posts/交替放置的玻璃杯题解/ 最后更新于 2025-04-13,距今已过 376 天
部分内容可能已过时
printsdf's Blog