USACO 2015 December Contest Gold Division - High Card Low Card (Gold)#
Problem link: here
Solution Author: Stefan Dascalescu
Problem Solution#
We can solve this problem greedily.
You can assume Bessie uses only her largest \(N/2\) cards in the first half (high-wins rounds) and only her smallest \(N/2\) cards in the second half (low-wins rounds).
For the first half (high-wins): for Elsie’s card \(e\), if possible play the smallest Bessie card \(> e\) (wins and preserves larger cards); otherwise, discard your smallest card (you can’t win this round anyway).
For the second half (low-wins): for Elsie’s card \(e\), if possible play the largest Bessie card \(< e\) (wins and preserves even smaller cards for tougher future \(e\)); otherwise, discard your smallest card (no card can be \(< e\)).
Time complexity is \(O(N \log N)\) using ordered sets.
Source code#
The source code in C++ can be seen below.
#include <cstdio>
#include <iostream>
#include <set>
#include <vector>
using namespace std;
void solve() {
int n;
cin >> n;
vector<int> elsie(n);
vector<bool> used(2 * n + 1, false);
for (int i = 0; i < n; i++) {
cin >> elsie[i];
used[elsie[i]] = true;
}
vector<int> bessie;
bessie.reserve(n);
for (int x = 1; x <= 2 * n; x++)
if (!used[x])
bessie.push_back(x);
int half = n / 2;
set<int> lowHalf, highHalf;
for (int i = 0; i < half; i++)
lowHalf.insert(bessie[i]);
for (int i = half; i < n; i++)
highHalf.insert(bessie[i]);
int ans = 0;
for (int i = 0; i < half; i++) {
int e = elsie[i];
auto it = highHalf.upper_bound(e);
if (it != highHalf.end()) {
ans++;
highHalf.erase(it);
} else {
highHalf.erase(highHalf.begin());
}
}
for (int i = half; i < n; i++) {
int e = elsie[i];
auto it = lowHalf.lower_bound(e);
if (it == lowHalf.begin()) {
if (!lowHalf.empty()) {
auto jt = lowHalf.end();
--jt;
lowHalf.erase(jt);
}
} else {
--it;
ans++;
lowHalf.erase(it);
}
}
cout << ans << '\n';
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
freopen("cardgame.in", "r", stdin);
freopen("cardgame.out", "w", stdout);
int t = 1;
while (t--)
solve();
return 0;
}