USACO 2017 February Contest Silver Division - Why Did the Cow Cross the Road#
Problem link: here
Solution Author: Stefan Dascalescu
Problem Solution#
Greedy solution: We sort both cows and chicken and we match the pairs greedily, as we match them in increasing order of the values.
Binary search solution: Similar to the greedy solution, we can find for each cow the smallest chicken which has a larger value than the value of the current cow.
Source code#
The source code in C++ can be seen below.
Greedy solution#
#include <bits/stdc++.h>
using namespace std;
int c, n, ans;
int main() {
ifstream cin("helpcross.in");
ofstream cout("helpcross.out");
cin >> c >> n;
vector<pair<int, int>> a(n); // cows
vector<int> b(c); // chicken
for (auto& it : b) {
cin >> it;
}
for (auto& it : a) {
cin >> it.first >> it.second;
}
sort(a.begin(), a.end());
sort(b.begin(), b.end());
priority_queue<int> pq;
int idx = 0;
for (auto& it : b) {
while (idx < n && a[idx].first <= it) {
pq.push(-a[idx++].second);
}
while (!pq.empty() && -pq.top() < it) {
pq.pop();
}
if (!pq.empty()) {
++ans;
pq.pop();
}
}
cout << ans << '\n';
return 0;
}
Binary search solution#
#include <iostream>
#include <vector>
#include <fstream>
#include <algorithm>
using namespace std;
int c, n;
vector<int> chickens;
vector<pair<int, int>> cows;
bool compare(const pair<int, int>& a, const pair<int, int>& b) {
return a.second < b.second;
}
int search(int target) {
//want to find smallest that is larger than target
int low = 0;
int high = c - 1;
int mid;
int works = -1;
while (low <= high) {
mid = (low + high) / 2;
if (chickens[mid] >= target) {
high = mid - 1;
works = mid;
}
else {
low = mid + 1;
}
}
return works;
}
int main() {
ifstream cin("helpcross.in");
ofstream cout("helpcross.out");
cin >> c >> n;
chickens.resize(c);
cows.resize(n);
for (int i = 0; i < c; i++) {
cin >> chickens[i];
}
for (int i = 0; i < n; i++) {
cin >> cows[i].first >> cows[i].second;
}
int counter = 0;
sort(chickens.begin(), chickens.end());
sort(cows.begin(), cows.end(), compare);
for (auto i: cows) {
int a = i.first;
int b = i.second;
int temp = search(a);
if (temp != -1 && chickens[temp] <= b) {
counter++;
chickens.erase(chickens.begin() + temp);
c--;
}
}
cout << counter << '\n';
return 0;
}