【发布时间】:2016-09-24 01:13:02
【问题描述】:
这是来自 Codechef 的问题,但请多多包涵。 https://www.codechef.com/ZCOPRAC/problems/ZCO16001
该竞赛是为准备在印度举行的区域计算奥林匹克竞赛而举办的,所以它不是我能从中获得收益的竞争性竞赛。只需要一点帮助来看看我的代码有什么问题,因为我觉得我忽略了一些大而愚蠢的事情。 :P
所以基本上问题总结如下。
假设有两个向量或数组。你需要换 它们之间的元素使得它们的最大元素之和 是最小值。但是,您最多可以交换 K 次。然后输出 这个总和的值。
我的方法很简单。取 Vector1 (V1) 中的最高数字,并将其与 V2 中的最低数字交换。添加每个的最高值。做同样的事情,但这次将 V2 中的最高数字与 V1 中的最低数字交换。添加每个的最高值。更好的交换将是总和最小的交换,并从那里继续 K 次。
例如:
V1 = 5 6 7 9
V2 = 9 10 5 4
在这种情况下,如果 K = 1 我首先将 V1 的 9 与 V2 的 4 交换。这给出了:
V1 = 5 6 7 4
V2 = 9 10 5 9
与之前的 19 相比,最高数字的总和为 17。我可以做的第二次交换是 V2 中的 10 与 V1 中的 5:
V1 = 10 6 7 4
V2 = 9 5 5 9
这样总和为 19,所以第一次交换更好,输出应该是 17。
这是我的解决方案:
#include <iostream>
#include <vector>
#include <algorithm>
#define print(vec) for (int i = 0; i < vec.size(); i++) { cout << vec[i] << " "; } cout << endl;
using namespace std;
vector <long long int> s1, s2;
inline long long int calc(vector <long long int> v1, vector<long long int> v2) {
return *max_element(v1.begin(), v1.end()) + *max_element(v2.begin(), v2.end());
}
int main(){
long long int n, k;
cin >> n >> k;
long long int x;
for (unsigned int i = 0; i < n; i++) {
cin >> x;
s1.push_back(x);
}
for (unsigned int i = 0; i < n; i++) {
cin >> x;
s2.push_back(x);
}
while (k--) {
vector <long long int> b1(s1);
vector <long long int> b2(s2);
long long int skewb = calc(b1,b2);
vector <long long int> v1(s1);
vector <long long int> v2(s2);
auto mn1 = minmax_element(v1.begin(), v1.end());
auto mn2 = minmax_element(v2.begin(), v2.end());
iter_swap(mn1.second, mn2.first);
b1 = vector <long long int> (v1);
b2 = vector <long long int> (v2);
skewb = calc(v1,v2);
v1 = vector <long long int> (s1);
v2 = vector <long long int> (s2);
mn1 = minmax_element(v1.begin(), v1.end());
mn2 = minmax_element(v2.begin(), v2.end());
iter_swap(mn2.second, mn1.first);
if (calc(v1,v2) <= skewb) {
b1 = vector <long long int> (v1);
b2 = vector <long long int> (v2);
}
if (b1 == s1 && b2 == s2) cout << "LOL" << endl;
s1 = vector <long long int> (b1);
s2 = vector <long long int> (b2);
}
cout << calc(s1, s2) << endl;
}
请注意,这会进行所有交换,即 K。所以即使当前的安排是最好的,它仍然会交换一些值。早些时候,当当前的安排是最好的时候,我打破了。这样做的原因是因为我得到了所有测试用例,除了两个!猜猜更烦人的是,每个任务都有一个! :( 所以我意识到必须完成所有K个开关。但是,即使现在我弄错了 2 个测试用例,也一定有一些我忽略了的东西。
知道它是什么吗? 解决方案链接:https://www.codechef.com/viewsolution/11574501
顺便说一句,任务 1 的 K = 1。
【问题讨论】:
-
@tobi303,如果你阅读codechef上的声明,你就会明白一切。
-
对不起,我的意思是 max_element 和 element 而不是长度。我指的是我包含的 Codechef 问题的链接。
-
@AlexStone,请更新问题详情。直觉为什么你的算法是正确的?
-
你能告诉我你的哪些测试用例(任务#)在 codechef 法官上失败了。
-
@AlexStone 我提供了被接受的实现。但我建议你在阅读解释后自己编码。