I'm having trouble with a competitive programming problem, here it is.
Farmer John's N cows (1 <= N <= 100,000) are standing at various positions along
a long one-dimensional fence. The ith cow is standing at position x_i (an
integer in the range 0...1,000,000,000) and has breed b_i (either 'G' for
Guernsey or 'H' for Holstein). No two cows occupy the same position.
FJ wants to take a photo of a contiguous interval of cows for the county
fair, but we wants all of his breeds to be fairly represented in the photo.
Therefore, he wants to ensure that, for whatever breeds are present in the
photo, there is an equal number of each breed (for example, a photo with
all Holsteins is ok, a photo with 27 Holsteins and 27 Guernseys is ok, but a
photo with 10 Holsteins and 9 Guernseys is not ok). Help FJ take his fair
photo by finding the maximum size of a photo that satisfies FJ's
constraints. The size of a photo is the difference between the maximum and
minimum positions of the cows in the photo. It is possible that FJ could
end up taking a photo of just a single cow, in which case this photo would
have size zero.
PROBLEM NAME: fairphoto
INPUT FORMAT:
* Line 1: The integer N.
* Lines 2..1+N: Line i+1 contains x_i and b_i.
SAMPLE INPUT:
6
4 G
10 H
7 G
16 G
1 G
3 H
INPUT DETAILS:
There are six cows with breeds (from left to right) G, H, G, G, H, G.
OUTPUT FORMAT:
* Line 1: A single integer indicating the maximum size of a fair
photo.
SAMPLE OUTPUT:
7
OUTPUT DETAILS:
The largest fair photo Farmer John can take is of the middle 4 cows,
containing 2 Holsteins and 2 Guernseys.
My solution utilizes prefix sums.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
|
#include <iostream>
#include <algorithm>
using namespace std;
struct data {
char cow;
int pos;
int bin;
int psum;
} cows [100000];
bool comp (data a, data b) {
return a.pos<b.pos;
}
int main () {
int n;
cin>>n;
for (int i=1; i<=n; i++) {
cin>>cows[i].pos>>cows[i].cow;
}
for (int i=1; i<=n; i++) {
if (cows[i].cow=='G')
cows[i].bin=1;
else {
cows[i].bin=-1;
}
}
sort (cows, cows+n+1, comp);
cows[0].psum=0;
for (int i=1; i<=n; i++) {
cows[i].psum=cows[i].bin+cows[i-1].psum;
}
int first [n+1];
int last [n+1];
fill (first, first+n+1, -1);
for (int i=0; i<=n; i++) {
if (first[cows[i].psum]==-1)
first[cows[i].psum]=cows[i].pos;
if (first[cows[i].psum]!=-1){
if(first[cows[i].psum]>cows[i].pos)
first[cows[i].psum]=cows[i].pos;
}
}
fill (last, last+n+1, -1);
for (int i=0; i<=n; i++) {
if (last[cows[i].psum]==-1)
last[cows[i].psum]=cows[i].pos;
if (last[cows[i].psum]!=-1){
if(last[cows[i].psum]<cows[i].pos)
last[cows[i].psum]=cows[i].pos;
}
}
int temp[n+1];
for (int i=0; i<=n; i++) {
temp[i]=cows[i].pos;
}
int dist [n+1];
for (int i=0; i<=n; i++) {
int ind=upper_bound(temp, temp+n+1, first[i])-temp;
dist[i]=last[i]-cows[ind].pos;
}
int max=dist[max_element(dist, dist+n+1)-dist];
int cd [n+1];
for (int i=1; i<=n; i++) {
int j=i;
while (j<n&&cows[j].cow==cows[j+1].cow) {
j++;
}
cd[i]=cows[j].pos-cows[i].pos;
}
int maxx=cd[max_element (cd, cd+n+1)-cd];
if (maxx>max)
cout<<maxx<<endl;
else {
cout<<max;
}
}
|
My solution utilizes prefix sums. What I essentially do is denote Guernseys as 1 and Holsteins as -1. Thus, an valid photo of cows with equal numbers of these two breeds will have a sum of zero. Given an array that represents our cows, we can quickly find the sums of various blocks of cows by taking the prefix sums of this array. For each cow at position k, we store a number S_k representing the sum of the cows' numbers from 1 to k. To find the sum of cows' numbers from i to j, we can simply compute S_j - S_(i-1). For a photo with i to k cows, the prefix sums of the i-1th cow and kth cow essentially must be equal.
I then store the leftmost position of the cow with each distinct prefix number, and do the same for the rightmost cow. I then store the difference in these positions in an array and find the maximum distance out of all possible prefix number pairs.
I then tackle the corner case of all cows being the same breed by find largest continued section of same breed and finding the distance accrodingly.
Then I compare the distance for the longest continuous section of same breed with the longest photo with equal numbers of both breeds and output the largest one.
I read the solution after I coded this, but it was in pseudocode, and had many obvious errors, so I did not really understand how to implement some of the things in the solution.
1. There is apparently some way to calculate the difference in distance without actually making an array for the rightmost cow, which would make my solution more efficient, as currently it does not run for very large inputs in time.
2. Apparently I have to double some array value or index thing so that it is 2n? to prevent out of bounds or something. it has to do with the prefix sum being a minimum of -n and max of n (all holsteins or all the other breed).
I know that was a mouthful. Thanks for making it to the end!