Practice
Div-3 Contest
Div-2 Contest
Author & Editorialist: Andrew Kostianoy
Tester: Radoslav Dimitrov
DIFFICULTY:
CAKEWALK
PREREQUISITES:
Greedy
PROBLEM:
You’re given two multisets of integers. You can swap any two integers from diffrent multisets. You want to perform as few swaps as possbile in such a way that sum of elements of the first multiset is greater than sum of elements of the second multiset.
QUICK EXPLANATION:
It’s always profitable to swap the smallest integer from the first multiset (let’s call it x) with the biggest integer from the second multiset (let’s call it y). If x \geq y and the winning condition isn’t met you should print -1.
EXPLANATION:
First of all, let’s see what happens when we swap two integers from different multisets. Let’s call sum of elements of the first multiset before swap SA_1. Similarly we can define SB_1. Let’s call integer that will be deleted from the first multiset x. Let’s call integer that will be deleted from the second multiset y. So new sum of elements of the first multiset will be SA_1 - x + y and new sum of elements of the second multiset will be SB_1 - y + x.
Since we want sum of elements of the first multiset to be greater than sum of elements of the second multiset it’s always profitable to swap the smallest integer from the first multiset with the biggest integer from the second multiset. Let’s prove this fact.
Indeed let’s call the smallest integer from the first multiset sml and another one that we want to swap bad. \Delta = bad - sml. We can notice that if we will swap sml instead of bad new sum of elements of the first multiset will increase by \Delta and new sum of elements of the second multiset will decrease by \Delta and since \Delta always \geq0 (sml \leq bad) the result won’t be worse.
In similar manner we can prove this fact for the biggest integer from the second multiset. So now we can just simulate this process:
- if sum of elements of the first multiset is bigger than sum of elements of the second multiset we should stop the process and print value of counter;
- In other case let’s find x and y.
- If x \geq y print -1;
- if x < y swap them and add 1 to counter.
Complexity of the solution: O(n^2)
SOLUTIONS:
Setter's Solution
#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
const int M = 1010;
int n, m, a[N], b[M];
int main(){
ios_base::sync_with_stdio(0); cin.tie(0);
// freopen("input2.txt","r",stdin);
// freopen("output2.txt","w",stdout);
int qq; cin >> qq;
for (; qq; qq--){
cin >> n >> m;
int sum_a = 0;
int sum_b = 0;
int ans = 0;
for (int i = 0; i < n; i++){
cin >> a[i];
sum_a += a[i];
}
for (int i = 0; i < m; i++) {
cin >> b[i];
sum_b += b[i];
}
while (sum_a <= sum_b){
int mn_a = int(1e9), loc_a = -1;
int mx_b = -1, loc_b = -1;
for (int i = 0; i < n; i++)
if (a[i] < mn_a){
mn_a = a[i];
loc_a = i;
}
for (int i = 0; i < m; i++)
if (b[i] > mx_b){
mx_b = b[i];
loc_b = i;
}
if (mn_a >= mx_b){
ans = -1;
break;
}
ans++;
swap(a[loc_a], b[loc_b]);
sum_a -= mn_a;
sum_a += mx_b;
sum_b += mn_a;
sum_b -= mx_b;
}
cout << ans << '\n';
}
return 0;
}
Tester's Solution
#include <bits/stdc++.h>
#define endl '\n'
#define SZ(x) ((int)x.size())
#define ALL(V) V.begin(), V.end()
#define L_B lower_bound
#define U_B upper_bound
#define pb push_back
using namespace std;
template<class T, class T1> int chkmin(T &x, const T1 &y) { return x > y ? x = y, 1 : 0; }
template<class T, class T1> int chkmax(T &x, const T1 &y) { return x < y ? x = y, 1 : 0; }
const int MAXN = (1 << 20);
int n, m;
int a[MAXN], b[MAXN];
void read() {
cin >> n >> m;
for(int i = 0; i < n; i++) cin >> a[i];
for(int i = 0; i < m; i++) cin >> b[i];
}
void solve() {
sort(a, a + n);
sort(b, b + m);
int sum_a = 0, sum_b = 0;
for(int i = 0; i < n; i++) sum_a += a[i];
for(int i = 0; i < m; i++) sum_b += b[i];
if(sum_a > sum_b) {
cout << 0 << endl;
return;
}
for(int i = 1; i <= min(n, m); i++) {
sum_a -= a[i - 1];
sum_b -= b[m - i];
sum_b += a[i - 1];
sum_a += b[m - i];
if(sum_a > sum_b) {
cout << i << endl;
return;
}
}
cout << -1 << endl;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin >> T;
while(T--) {
read();
solve();
}
return 0;
}