[Usaco2014 Open]Fair Photography
题目
Description
农夫John(以后简称“FJ”)的N头奶牛站在一个一维长篱笆上的不同位置 (1 <= N <= 100,000)。第i头奶牛站在
位置x_i (一个处于范围0...1,000,000,000的整数),其品种为b_i(要么为‘G’,表示根西种Guernsey,要么为
‘H’,表示霍斯坦种Holstein)。每头奶牛的位置各不相同。FJ想要为一段连续区间内的奶牛拍张照片,用来参
加郡里的展览会,但是他想让照片里各个品种奶牛的数量是“公平的”。所以,他想要使得无论照片里出现了多少
个品种的奶牛,这些品种奶牛的数量必须相同(例如,一张照片里可以全是霍斯坦种奶牛,也可以出现27头根西种
奶牛和27头霍斯坦种奶牛,但不能出现10头霍斯坦种奶牛和9头根西种奶牛,这种情况下各个品种数量不同)。帮
助FJ拍一张满足其要求的最大尺寸照片。一张照片的尺寸为照片中最左边的奶牛和最右边的奶牛的位置差。可能FJ
拍出的照片里只有一头奶牛,此时照片的尺寸为0。
位置x_i (一个处于范围0...1,000,000,000的整数),其品种为b_i(要么为‘G’,表示根西种Guernsey,要么为
‘H’,表示霍斯坦种Holstein)。每头奶牛的位置各不相同。FJ想要为一段连续区间内的奶牛拍张照片,用来参
加郡里的展览会,但是他想让照片里各个品种奶牛的数量是“公平的”。所以,他想要使得无论照片里出现了多少
个品种的奶牛,这些品种奶牛的数量必须相同(例如,一张照片里可以全是霍斯坦种奶牛,也可以出现27头根西种
奶牛和27头霍斯坦种奶牛,但不能出现10头霍斯坦种奶牛和9头根西种奶牛,这种情况下各个品种数量不同)。帮
助FJ拍一张满足其要求的最大尺寸照片。一张照片的尺寸为照片中最左边的奶牛和最右边的奶牛的位置差。可能FJ
拍出的照片里只有一头奶牛,此时照片的尺寸为0。
Input
第1行:整数N。
第2..1+N行:第i+1行包含x_i和b_i。
第2..1+N行:第i+1行包含x_i和b_i。
Output
第1行:一个整数,表示一张“公平的”照片的最大尺寸。
Sample Input
6
4 G
10 H
7 G
16 G
1 G
3 H
【输入说明】
有6头奶牛(从左到右)品种分别为G, H, G, G, H, G。
Sample Output
7
【输出说明】
FJ可以拍出的最大尺寸“公平的”照片是出现中间4头奶牛的照片,包括了2头霍斯坦种奶牛和2头根西种奶牛。
思路:
先坐标排序
然后,确定一个区间内同种奶牛数量相等,请看
https://www.cnblogs.com/wzx-RS-STHN/p/13049823.html
也是我写的^_^,懒得再写了
那么这题不同的是,可以满足区间内为同一种牛;
那么就需要统计最长的连续同种牛的长度;
如: 100001 最长的连续同种牛的长度是4
(但题目句子:一张照片的尺寸为照片中最左边的奶牛和最右边的奶牛的位置差)
所以按题意最长的连续同种牛的长度是3;
对于具体怎么求 最长的连续同种牛的长度 请看代码注释
最后再拿 最长的连续同种牛的长度 与 两种牛数量相等的最长区间长度 求最大值就好了
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 inline ll read() 5 { 6 ll a=0,f=1; char c=getchar(); 7 while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();} 8 while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();} 9 return a*f; 10 } 11 struct sbbb 12 { 13 ll x,y; 14 }a[500001]; 15 ll n,ans,num,f[500001]; 16 inline ll cmp(sbbb a,sbbb b) 17 { 18 return a.y<b.y; 19 } 20 int main() 21 { 22 n=read(); 23 for(ll i=1;i<=n;i++) 24 { 25 char c; 26 a[i].y=read(); 27 cin>>c; 28 if(c=='G') 29 a[i].x=1; 30 else 31 a[i].x=-1;//不懂为什么要这样转的,看题解思路中的网址 32 } 33 sort(a+1,a+n+1,cmp);//按坐标排序 34 ll t=0,tt=0,mt=0,mtt=0;//t代表1的连续长度,mt代表1的最长连续长度; 35 //tt代表-1的连续长度,mtt代表-1的最长连续长度 36 if(a[1].x==1)//第一个在外统计 37 t+=a[1].y; 38 else 39 tt+a[1].y; 40 for(ll i=2;i<=n;i++) 41 { 42 if(a[i].x==1) 43 { 44 if(a[i-1].x==1)//如果当前位置的数字与前一个位置的数字都是1 45 t+=a[i].y-a[i-1].y;//那么利用前缀求 当前位置与前一个位置相距的长度 46 if(a[i-1].x==-1)//如果当前位置的数字与前一个位置的数字不一样 47 t=0;//重新统计 1的连续长度 48 } 49 mt=max(mt,t);//计算最长连续长度 50 if(a[i].x==-1)//-1的最长连续长度统计,同上 51 { 52 if(a[i-1].x==-1) 53 tt+=a[i].y-a[i-1].y; 54 if(a[i-1].x==1) 55 tt=0; 56 } 57 mtt=max(mtt,tt); 58 } 59 ll anss=max(mtt,mt);//把 -1的最长连续长度与 1的最长连续长度 求最大值 60 for(ll i=1;i<=n;i++) 61 {//两种牛数量相等的最长区间长度 ,不懂的,看题解思路中的网址 62 num+=a[i].x; 63 if(!f[num+n]) 64 f[num+n]=i; 65 else 66 ans=max(ans,a[i].y-a[f[num+n]+1].y); 67 } 68 printf("%lld",max(anss,ans));//最后求一次最大值 69 }