模拟,区间覆盖,区间合并
题目的思路就是用黑的段去更新白的段,然后合并白的段。更新时,如果全被黑的覆盖了,则令白段的左位置为0。
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
struct Node {
int l, r;
}ns[40005];
int len, n;
bool cmp( Node nd1, Node nd2 ) {
return nd1.l < nd2.l;
}
void black( int a, int b ) {
int i;
for( i=0; i<len; ++i ) {
if( ns[i].l == 0 ) continue; //更新时有4中情况
if( a > ns[i].l && a <= ns[i].r && b >= ns[i].r ) ns[i].r = a - 1; //1.只对右端点更新
else if( a <= ns[i].l && b >= ns[i].l && b < ns[i].r ) ns[i].l = b + 1; //2.只对左端点更新
else if( a > ns[i].l && b < ns[i].r ) { //3.同时对左右端点更新
ns[len].l = b + 1;
ns[len].r = ns[i].r;
ns[i].r = a - 1;
len ++;
} else if( a <= ns[i].l && b >= ns[i].r ) { //4.黑的把白的全部覆盖
ns[i].l = 0;
}
}
}
void white() {
int i;
sort( ns, ns+len, cmp );
for( i=1; i<len; ++i ) {
if( ns[i-1].l == 0 ) continue;
if( ns[i-1].r + 1 >= ns[i].l ) { //排序后合并时2种情况
ns[i].l = ns[i-1].l; //1.可以拓展第i段的左端点
if( ns[i-1].r > ns[i].r ) ns[i].r = ns[i-1].r; //2.可以拓展第i段的右端点
}
}
}
int main() {
// freopen( "c:/aaa.txt", "r", stdin );
char c;
int a, b, maxx, p, i;
while( scanf( "%d", &n ) == 1 ) {
len = 0;
while( n-- ) {
scanf( "%d %d %c", &a, &b, &c );
if( a > b ) swap( a, b );
if( c == 'w' ) {
ns[len].l = a;
ns[len].r = b;
len ++;
} else black( a, b );
}
white();
maxx = 0;
p = 0;
for( i=0; i<len; ++i ) {
if( ns[i].l == 0 ) continue;
if( ns[i].r - ns[i].l + 1 > maxx ) {
maxx = ns[i].r - ns[i].l + 1;
p = i;
}
}
printf( "%d %d\n", ns[p].l, ns[p].r );
}
return 0;
}
浙公网安备 33010602011771号