试题 C:三国游戏
因为当满足 X > Y + Z X>Y+Z X>Y+Z 时有国家获胜,游戏结束,所以我们可以把魏蜀吴三国分开考虑。
- 用数组
a
、b
、c
读取输入值 - 对数组
a
、b
、c
分别计算 X − Y − Z X-Y-Z X−Y−Z 的数值( X X X 代表当前国家, Y Y Y、 Z Z Z 代表另外两个国家) - 对处理后的数组
a
、b
、c
降序排序 - 从前往后依次遍历求和,只要有一方的前缀和大于
0
便继续操作,直至任何一方的前缀和都小于0
此题运用了贪心思想(对处理后的数组 a
、b
、c
降序排序),可以证明对排序后的数组 a
、b
、c
进行上述遍历能够得到正确结果。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
#define For(i, x) for(int i = 0; i < x; i++)
int main() {
int n;
cin >> n;
vector<int> a(n);
vector<int> b(n);
vector<int> c(n);
// 读取输入值
For(i, n) cin >> a[i];
For(i, n) cin >> b[i];
For(i, n) cin >> c[i];
// 魏蜀吴分别处理
For(i, n) {
int u = a[i], v = b[i], w = c[i];
a[i] = u - v - w;
b[i] = v - u - w;
c[i] = w - u - v;
}
// 降序排序
sort(a.begin(), a.end(), greater<int>());
sort(b.begin(), b.end(), greater<int>());
sort(c.begin(), c.end(), greater<int>());
long sum_a = 0, sum_b = 0, sum_c = 0;
int ans = -1;
For(i, n) {
sum_a += a[i];
sum_b += b[i];
sum_c += c[i];
// 只要有一个大于0就继续算,否则退出循环
if (sum_a > 0 || sum_b > 0 || sum_c > 0) {
ans = i + 1;
} else break;
}
cout << ans << endl;
return 0;
}