题目:
Description
Farmer John has decided to take a family portrait of some (maybe
all) of the cows. In order to take the portrait, FJ has arranged
all N (1 <= N <= 50,000) cows in a straight line. Each cow is labeled
with its x coordinate (range: 0..1,000,000,000) on the line as well
as its breed (0 or 1).
Over the years, FJ has done some crazy things, and this activity
is no exception. He will only photograph one group of cows, and
that group must be "balanced". A contiguous group of cows is
"balanced" if it contains the same number of cows from each of the
two breeds.
Determine the widest expanse of cows that might have to fit in one
photograph. The length of a balanced group is the difference in x
values between the left-most and right-most cows in the group.
At least one cow of each breed appears in the input, and no two
cows share the same x coordinate.
Input
* Line 1: A single integer: N
* Lines 2..N+1: Each line contains two space-separated integers that
describe a single cow containing respectively: a breed ID and
an x coordinate
Output
* Line 1: A single integer specifying the size of the largest
contiguous balanced group of cows.
Sample Input
7 0 11 1 10 1 25 1 12 1 4 0 13 1 22
Sample Output
11
Hint
Cows #1 (at 11), #4 (at 12), #6 (at 13), and #7 (at 22) form a contiguous balanced group occupying 22-11=11 units of length on the number line:
<-------- balanced group --------> 1 1 0 1 0 1 1 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 0 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
--------------------------------------------------------------------分割线
思路:
输入n头牛的类型及坐标,找到坐标上连续的牛中如果满足两种类型相等的最长的坐标区域。
题目给了5s的时间,一开始尝试用了一下暴力的方法,对坐标进行排序之后遍历每一头牛并找从该牛开始的最长区域,结果理所当然的超时了。
看了一下别人的方法,可以将类型0改为-1,用一个数组sums记录到每一位的类型数的前缀和。这样如果第i位于后面第j位的和是相等的,就说明第i+1到第j位之间的牛是两种类型相等的。题目可以转化成为在sums数组中找到两个位置i,j满足sums[i]=sums[j],而且使得第i+1头牛的x坐标和第j头的x坐标差值最大(区域最大)
为了实现时间复杂度O(n),只遍历一次sums数组,并另开一个数组sums_position,记录每一个sum出现的位置。
n头牛的sums取值范围是[-n,n],sums_position数组初始化每一个位置为0,对于sums[i],如果该位置仍为0,则说明第一次遇到这个值。否则该位置已经存放上一次遇到这个值时遍历到的位置。
1 #include<iostream> 2 #include<algorithm> 3 using namespace std; 4 5 const int Max_num=50000; 6 7 struct Cow{ 8 int bleed; 9 int x; 10 }; 11 12 Cow cows[Max_num+1]; 13 int sums[Max_num+1]; 14 int sums_position[Max_num*2+1]={0}; //the index 0 in cows and sums is not used. 15 16 bool cmp(const Cow &c1,const Cow &c2){ 17 return c1.x<c2.x; 18 } 19 20 int main(){ 21 int n,max=0; //max is the size of the largest contiguous balanced group of cows. 22 cin>>n; 23 for(int i=1;i<=n;i++){ 24 cin>>cows[i].bleed>>cows[i].x; 25 if(cows[i].bleed==0) 26 cows[i].bleed=-1; //convenient to count the sum. 27 } 28 sort(cows+1,cows+n+1,cmp);//cows are rearranged in the order of x. 29 sums[0]=0; //set but not used. 30 for(int i=1;i<=n;i++){ 31 sums[i]=sums[i-1]+cows[i].bleed; 32 if(sums_position[sums[i]]==0) //this sum value is first met 33 sums_position[sums[i]]=i; 34 else{ //meet the same sum value again,and renew the max if necessarily 35 if(max<cows[i].x-cows[sums_position[sums[i]]+1].x) 36 max=cows[i].x-cows[sums_position[sums[i]]+1].x; 37 } 38 } 39 cout<<max<<endl; 40 return 0; 41 }