Description
有一根长度为1000000000的棍子,一开始涂成白色。
棍子上有刻度,左端点为0,右端点1000000000。
由于某种原因这根棍子的某些部分被重新涂过了。
重新涂的颜色可能是黑色或着白色。
棍子总共被依次重新涂了N(1<=N<=5000)次。
找出最后最长的白色段。
Input
第1行一个数N。
接下来N行表示一次涂色,格式如下:
ai bi ci
ai和bi为整数,ci是字母b或w。
表示把ai和bi之间那段涂成ci色(w白色,b黑色)。
0<=ai<=bi<=1000000000。
Output
一行,两个数x和y(x如果有多个最长的段,输出x最小的一个。
Sample Input
4
1 999999997 b
40 300 w
300 634 w
43 47 b
Sample Output
47 634
分析
将所有数离散到数组里,然后暴力进行一下枚举
注意:一开始所有都是白色的
程序:
#include<iostream>
using namespace std;
int l[10003],a[5002],b[5002],n;
char color[10003],c[5002],s;
void kp(int l,int r);
void work();
int main()
{
cin>>n;
n++;
a[1]=0;b[1]=1000000000;
c[1]='w';
l[1]=0;l[2]=b[1];
for (int i=2;i<=n;i++)
{
cin>>a[i]>>b[i]>>c[i];
l[i*2-1]=a[i];
l[i*2]=b[i];
}
kp(1,2*n);
work();
return 0;
}
void kp(int l1,int r)
{
int i,j,mid,t;
i=l1;j=r;mid=l[(i+j)/2];
do
{
while (l[i]<mid) i++;
while (l[j]>mid) j--;
if (i<=j)
{
t=l[i];l[i]=l[j];l[j]=t;
i++;j--;
}
}
while (i<j);
if (l1<j) kp(l1,j);
if (i<r) kp(i,r);
}
void work()
{
int ans,ansi,ansj,ti,tj,now;
for (int i=1;i<=2*n-1;i++)
{
for (int j=1;j<=n;j++)
if (l[i]>=a[j]&&l[i+1]<=b[j]) color[i]=c[j];
}
ans=0;
int i=1;
char s='w';
do
{
if (color[i]==s)
{
ti=i;
tj=ti+1;
now=0;
while (color[tj]==s&&tj<=2*n)
{
now=now+l[tj]-l[tj-1];
tj=tj+1;
}
now=now+l[tj]-l[tj-1];
if (now>ans)
{
ans=now;
ansi=ti;
ansj=tj;
}
i=tj;
}
i++;
}
while (i<2*n);
cout<<l[ansi]<<' '<<l[ansj];
}