离散化每一条白色线段,然后不停地向右延伸或者覆盖每一条线段的两个端点,同时记录下最长的距离和端点位置,这题也可以用离散化+线段树做
#include <iostream>
using namespace std;
const int size = 2011;
struct Se
{
int l, r;
}a[size];
int x, y;
char c;
bool cmp(Se a, Se b)
{
return a.l < b.l;
}
int main()
{
//freopen("IN.txt", "r", stdin);
//freopen("OUT.txt", "w", stdout);
int n;
while (scanf("%d", &n) != EOF){
int num = 0;
for (int i = 0; i < n; i ++){
scanf("%d%d %c", &x, &y, &c);
if (x>y)swap(x, y);
if (c == 'w'){
a[num].l = x;
a[num ++].r = y;
}
else {
int temp = num;
for (int j = 0; j < temp; j ++){
if (x <= a[j].l && y >= a[j].r){//如果黑色线段完全覆盖掉了白色线段
a[j].l = a[j].r = -1;
}
else
if (x <= a[j].l && y >= a[j].l && y <= a[j].r){//如果黑色覆盖掉了白色线段的左端点
a[j].l = y+1;
}
else
if (x >= a[j].l && y >= a[j].r && x <= a[j].r){//如果黑色覆盖掉了白色线段的右端点
a[j].r = x-1;
}
else
if (x > a[j].l && y < a[j].r){//如果黑色线段只覆盖掉白色线段中间的一部分
a[num].l = y+1, a[num ++].r = a[j].r;
a[j].r = x-1; //右端点的位置一定要最后才覆盖
}
}
}
}
sort(a, a+num, cmp);
int ll, rr, maxx;
ll = rr = maxx = -1;
int ansl, ansr;
for (int i = 0; i < num ; i ++){
if (a[i].l != -1){
if (a[i].l <= rr+1){
rr = max(a[i].r, rr); //延伸右端点位置
}
else {
ll = a[i].l, rr = a[i].r;
}
if (maxx < rr-ll+1){
maxx = rr-ll+1, ansl = ll, ansr = rr;
}
}
}
if (maxx == -1)printf("Oh, my god\n");
else
printf("%d %d\n", ansl, ansr);
}
return 0;
}