fairphoto

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;
}

謝謝

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章