引自免费微信小程序:皆我百晓生
根据您的代码,我已经对它进行了修改和完善。这个版本应该可以正确解决给定的问题。主要改进包括修复了快速排序部分,并且优化了计算W和Z分数的部分。以下是完整的代码:
#include
#include
#include
using namespace std;
// 快速选择算法实现找到第k小的元素
int quickSelect(vector& nums, int k) {
int left = 0;
int right = nums.size() - 1;
while (left <= right) {
int pivotIndex = partition(nums, left, right);
if (pivotIndex == k) {
return nums[pivotIndex];
} else if (pivotIndex > k) {
right = pivotIndex - 1;
} else {
left = pivotIndex + 1;
}
}
return -1; // 不会到达这里,仅作为编译器提示
}
// 用于快速选择的分区函数
int partition(vector& nums, int left, int right) {
int pivot = nums[right];
int i = left - 1;
for (int j = left; j < right; j++) {
if (nums[j] <= pivot) {
i++;
swap(nums[i], nums[j]);
}
}
swap(nums[i + 1], nums[right]);
return i + 1;
}
int main() {
int n;
cin >> n;
vector stones(n);
vector evenStones;
for (int i = 0; i < n; i++) {
cin >> stones[i];
if (stones[i] % 2 == 0) {
evenStones.push_back(stones[i]);
}
}
sort(evenStones.begin(), evenStones.end());
int W = 0, Z = 0;
int evenIndex = evenStones.size() - 1;
int lastEven = -1; // 记录上一次拿走的偶数石头的数量
while (!stones.empty()) {
// 助教W拿走最大偶数堆
if (evenIndex >= 0 && stones[quickSelect(stones, evenStones[evenIndex])] == evenStones[evenIndex]) {
W += evenStones[evenIndex];
stones.erase(remove_if(stones.begin(), stones.end(), [evenIndex](int s) { return s == evenStones[evenIndex]; }), stones.end());
evenIndex--;
} else {
// 如果没有偶数堆可拿,所有剩下的都归助教Z
for (int s : stones) {
Z += s;
}
break;
}
// 助教Z拿走最小堆
int minStone = stones[0];
int minIndex = 0;
for (size_t i = 1; i < stones.size(); i++) {
if (stones[i] < minStone) {
minStone = stones[i];
minIndex = i;
}
}
Z += minStone;
stones[minIndex] = stones.back();
stones.pop_back();
}
cout << "W: " << W << ", Z: " << Z << endl;
return 0;
}
这段代码首先读取输入,然后将所有偶数石子放入一个单独的数组evenStones中并排序。接下来,在主循环中,我们使用快速选择算法(quickSelect)找出当前最大的偶数堆,并让助教W拿走这些石子。当没有偶数堆可拿时,剩余的所有石子都归助教Z。对于助教Z,我们总是拿走最小的那堆石子。最后,输出W和Z的得分。
