fairphoto
題目描述
給出n 個點,每個點都有一個座標xi,這些點中一些點是白點,另外的是黑點,求滿足以下兩個條件的最長的線段的長度
條件一:線段的左右端點都必須在給出的n 個點中
條件二:給出的n 個點中,被這條線段所包含的點中黑點個數必須等於白點個數(包括左右端點)
輸入
第1 行:一個整數n
第2..n+1 行:每行一個整數xi,表示點的座標,和一個字符(’G’ 表示黑點,’H’ 表示白點),中間用空格隔開,
輸出
一行一個數,最長的線段的長度
樣例輸入
6
4 G
10 H
7 G
16 G
1 G
3 H
樣例輸出
7
數據範圍限制
• 對於30% 的數據,n <= 10^3。
• 對於100% 的數據,n <= 10^5,1 <= xi <= 10^9。
這道題我們可以用貪心來做,我們將黑點賦爲-1,白點爲1,
然後我們去做前綴和,如果這樣的和沒有出現過(判斷這個數組是否爲零),
則用一個數組來記錄它的下標,沒有則到前面去找一個與它相對的和。
舉個栗子,假設當前這個前綴和多出了3個白點即和等於3,那我們
就去前邊找一個多出3個黑點的和即和等於-3.
code:
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,f[1000005],b[1000005];
char ch;
struct stu
{
int ans,num;
}a[1000005];
bool cmp(stu x,stu y)
{
return x.ans<y.ans;
}
int main()
{
freopen("fairphoto.in","r",stdin);
freopen("fairphoto.out","w",stdout);
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i].ans>>ch;
if(ch=='G')a[i].num=1;
else a[i].num=-1;
}
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;i++)
{
f[i]=f[i-1]+a[i].num;
if(f[i]==0)m=max(m,a[i].ans-a[1].ans);
if(f[i]>0)
{
if(b[f[i]]==0)b[f[i]]=i;
else m=max(m,a[i].ans-a[b[f[i]]+1].ans);
}
else
{
if(b[f[i]+n]==0)b[f[i]+n]=i;
else m=max(m,a[i].ans-a[b[f[i]+n]+1].ans);
}
}
cout<<m;
return 0;
}