#include <cstdio> #include <algorithm> #include <set> #include <map> #include <climits> #include <cassert> struct terrain_t; struct range_t { int a, b; terrain_t* t; range_t() {} range_t(int v) : a(v), b(v), t(NULL) {} void absorb(range_t& o) { if( o.a < a ) a = o.a; if( o.b > b ) b = o.b; } }; bool operator<(const range_t &a, const range_t &b) { return a.a < b.a; } enum { BEFORE = 0, AFTER = 1, DELETED = 2 }; struct terrain_t { range_t x, y; char state; void absorb(terrain_t& o) { x.absorb(o.x); y.absorb(o.y); o.state = DELETED; } }; bool operator<(const terrain_t &a, const terrain_t &b) { if( a.state != b.state ) return a.state < b.state; if( a.x.a != b.x.a ) return a.x.a < b.x.a; return a.x.b < b.x.b; } std::multimap<int, terrain_t*> queue; std::set<range_t> ranges; terrain_t T[100000]; int main() { int n; scanf("%d", &n ); for( int i = 0; i < n; i++ ) { scanf("%d %d %d %d", &T[i].x.a, &T[i].x.b, &T[i].y.a, &T[i].y.b ); T[i].x.t = T[i].y.t = T+i; } ranges.insert(range_t(INT_MIN)); ranges.insert(range_t(INT_MAX)); int territoriesLeft = n; int direction = false; while( true ) { direction = not direction; int beginTerritoriesLeft = territoriesLeft; for( int i = 0; i < n; i++ ) if( T[i].state != DELETED ) { queue.insert( std::make_pair(2*(direction ? T[i].y.a : -T[i].y.b), T+i) ); T[i].state = BEFORE; } while( not queue.empty() ) { range_t& x = queue.begin()->second->x; queue.erase(queue.begin()); switch(x.t->state) { case DELETED: break; case BEFORE: { std::set<range_t>::iterator it = ranges.lower_bound(range_t(x.b)); it--; while( it->b > x.a ) { x.t->absorb(*it->t); territoriesLeft--; std::set<range_t>::iterator rit = it; it--; ranges.erase(rit); } ranges.insert(x); queue.insert( std::make_pair(2*(direction ? x.t->y.b : -x.t->y.a)-1, x.t) ); x.t->state = AFTER; } break; case AFTER: ranges.erase(x); break; } } if( beginTerritoriesLeft == territoriesLeft ) break; } std::sort( T, T+n ); printf("%d\n", territoriesLeft ); for( int i = 0; i < territoriesLeft; i++ ) printf("%d %d %d %d\n", T[i].x.a, T[i].x.b, T[i].y.a, T[i].y.b); return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | #include <cstdio> #include <algorithm> #include <set> #include <map> #include <climits> #include <cassert> struct terrain_t; struct range_t { int a, b; terrain_t* t; range_t() {} range_t(int v) : a(v), b(v), t(NULL) {} void absorb(range_t& o) { if( o.a < a ) a = o.a; if( o.b > b ) b = o.b; } }; bool operator<(const range_t &a, const range_t &b) { return a.a < b.a; } enum { BEFORE = 0, AFTER = 1, DELETED = 2 }; struct terrain_t { range_t x, y; char state; void absorb(terrain_t& o) { x.absorb(o.x); y.absorb(o.y); o.state = DELETED; } }; bool operator<(const terrain_t &a, const terrain_t &b) { if( a.state != b.state ) return a.state < b.state; if( a.x.a != b.x.a ) return a.x.a < b.x.a; return a.x.b < b.x.b; } std::multimap<int, terrain_t*> queue; std::set<range_t> ranges; terrain_t T[100000]; int main() { int n; scanf("%d", &n ); for( int i = 0; i < n; i++ ) { scanf("%d %d %d %d", &T[i].x.a, &T[i].x.b, &T[i].y.a, &T[i].y.b ); T[i].x.t = T[i].y.t = T+i; } ranges.insert(range_t(INT_MIN)); ranges.insert(range_t(INT_MAX)); int territoriesLeft = n; int direction = false; while( true ) { direction = not direction; int beginTerritoriesLeft = territoriesLeft; for( int i = 0; i < n; i++ ) if( T[i].state != DELETED ) { queue.insert( std::make_pair(2*(direction ? T[i].y.a : -T[i].y.b), T+i) ); T[i].state = BEFORE; } while( not queue.empty() ) { range_t& x = queue.begin()->second->x; queue.erase(queue.begin()); switch(x.t->state) { case DELETED: break; case BEFORE: { std::set<range_t>::iterator it = ranges.lower_bound(range_t(x.b)); it--; while( it->b > x.a ) { x.t->absorb(*it->t); territoriesLeft--; std::set<range_t>::iterator rit = it; it--; ranges.erase(rit); } ranges.insert(x); queue.insert( std::make_pair(2*(direction ? x.t->y.b : -x.t->y.a)-1, x.t) ); x.t->state = AFTER; } break; case AFTER: ranges.erase(x); break; } } if( beginTerritoriesLeft == territoriesLeft ) break; } std::sort( T, T+n ); printf("%d\n", territoriesLeft ); for( int i = 0; i < territoriesLeft; i++ ) printf("%d %d %d %d\n", T[i].x.a, T[i].x.b, T[i].y.a, T[i].y.b); return 0; } |