涂 色 涂色 涂色
题目链接:SSL 2124
题目
有一根长度为
1000000000
1000000000
1000000000的棍子,一开始涂成白色。
棍子上有刻度,左端点为
0
0
0,右端点
1000000000
1000000000
1000000000。
由于某种原因这根棍子的某些部分被重新涂过了。
重新涂的颜色可能是黑色或着白色。
棍子总共被依次重新涂了
N
N
N次。
找出最后最长的白色段。
输入
第
1
1
1行一个数
N
N
N。
接下来
N
N
N行表示一次涂色,格式如下:
a
i
b
i
c
i
ai\ bi\ ci
ai bi ci
a
i
ai
ai和
b
i
bi
bi为整数,
c
i
ci
ci是字母
b
b
b或
w
w
w。
表示把
a
i
ai
ai和
b
i
bi
bi之间那段涂成
c
i
ci
ci色(
w
w
w白色,
b
b
b黑色)。
输出
一行,两个数 x x x和 y y y。 x x x如果有多个最长的段,输出 x x x最小的一个。
数据范围
1
<
=
N
<
=
5000
1<=N<=5000
1<=N<=5000
0
<
=
a
i
<
=
b
i
<
=
1000000000
0<=ai<=bi<=1000000000
0<=ai<=bi<=1000000000
样例输入
4
1 999999997 b
40 300 w
300 634 w
43 47 b
样例输出
47 634
思路
这道题是一道离散化。
我们离散化之后,就求出最长的白色线段,然后就可以了。
代码
#include<cstdio>
#include<algorithm>
#define ll long long
#define max(x, y) (x) > (y) ? (x) : (y)
using namespace std;
ll n, a[3][5001], b[10001], k, ansl, ansr, l, r;
bool color[5001];
char c;S
int main() {
scanf("%d", &n);//读入
a[2][0] = 2147483647;//初始化
for (int i = 1; i <= n; i++) {
scanf("%d %d", &a[1][i], &a[2][i]);//读入
getchar();//处理换行符
c = getchar();//读入
if (c == 'b') color[i] = 1;//是黑色
b[++k] = a[1][i];//记录
b[++k] = a[2][i];
}
sort (b + 1, b + k + 1);//离散化
for (ll i = 1; i <= k; i++)
for (ll j = n; j >= 0; j--)
if (b[i - 1] >= a[1][j] && b[i] <= a[2][j]) {//是否在区间内
if (color[j]) {//是否变成了黑色
if (r - l > ansr - ansl) {//比答案值更大
ansr = r;//更新
ansl = l;
}
l = b[i];//更新范围
r = b[i + 1];
}
if (b[i - 1] <= r) r = b[i];//更新最右值
break;//找到了就退出
}
printf("%lld %lld", ansl, ansr);//输出
return 0;
}