#define NDEBUG #include <cassert> #include <cctype> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <sstream> #include <algorithm> #include <queue> #include <string> #include <vector> #include <list> using namespace std; #define TRACE(x) cerr<<"# "#x<<endl; #define DEBUG(x) cerr<<#x<<" = "<<(x)<<endl; typedef unsigned long long ULL; typedef long long LL; const int INF = 0x7FFFFFFF; struct Tribe { int x1, x2, y1, y2; Tribe(int a, int b, int c, int d): x1(a), x2(b), y1(c), y2(d) {} }; int main() { int n, x1, x2, y1, y2; vector<Tribe> tribes; scanf("%d", &n); tribes.reserve(n + 1); for(int i=0; i<n ;++i) { scanf("%d %d %d %d", &x1, &x2, &y1, &y2); tribes.emplace_back( Tribe(x1,x2,y1,y2) ); } sort(tribes.begin(), tribes.end(), [](const Tribe &a, const Tribe &b) -> bool { return a.x1 < b.x1; }); #define GO_BACK 0 auto start = tribes.begin(); #if ! GO_BACK START: #endif for(auto first=start; first < tribes.end() ;++first) { #if GO_BACK START: #endif #ifndef NDEBUG fprintf(stderr, "first x: %d - %d y: %d - %d\n", first->x1, first->x2, first->y1, first->y2); #endif for(auto second=(first+1); second < tribes.end() ;++second) { #ifndef NDEBUG fprintf(stderr, " second x: %d - %d y: %d - %d\n", second->x1, second->x2, second->y1, second->y2); #endif if(second->x1 < first->x2) { if(second->y1 < first->y2) { if(second->y2 > first->y1) { // intersection - merge #ifndef NDEBUG fprintf(stderr, " merge\n"); #endif first->x2 = max(first->x2 , second->x2); first->y1 = min(first->y1 , second->y1); first->y2 = max(first->y2 , second->y2); tribes.erase(second); #if GO_BACK int left = min(first->x1,); while((first != start) && (first->x2 >= left)) { --first; } #endif goto START; } } } else { #ifndef NDEBUG fprintf(stderr, " no more intersections possible\n"); #endif break; } } } sort(tribes.begin(), tribes.end(), [](const Tribe &a, const Tribe &b) -> bool { if(a.x1 < b.x1) { return true; } else if(a.x1 == b.x1) { if(a.x2 < b.x2) { return true; } else if(a.x2 == b.x2) { if(a.y1 < b.y1) { return true; } else if(a.y1 == b.y1) { return (a.y2 < b.y2); } } } return false; }); printf("%u\n", static_cast<unsigned>(tribes.size())); for( const auto &t : tribes) { printf("%d %d %d %d\n", t.x1, t.x2, t.y1, t.y2); } 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 113 114 115 116 | #define NDEBUG #include <cassert> #include <cctype> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <sstream> #include <algorithm> #include <queue> #include <string> #include <vector> #include <list> using namespace std; #define TRACE(x) cerr<<"# "#x<<endl; #define DEBUG(x) cerr<<#x<<" = "<<(x)<<endl; typedef unsigned long long ULL; typedef long long LL; const int INF = 0x7FFFFFFF; struct Tribe { int x1, x2, y1, y2; Tribe(int a, int b, int c, int d): x1(a), x2(b), y1(c), y2(d) {} }; int main() { int n, x1, x2, y1, y2; vector<Tribe> tribes; scanf("%d", &n); tribes.reserve(n + 1); for(int i=0; i<n ;++i) { scanf("%d %d %d %d", &x1, &x2, &y1, &y2); tribes.emplace_back( Tribe(x1,x2,y1,y2) ); } sort(tribes.begin(), tribes.end(), [](const Tribe &a, const Tribe &b) -> bool { return a.x1 < b.x1; }); #define GO_BACK 0 auto start = tribes.begin(); #if ! GO_BACK START: #endif for(auto first=start; first < tribes.end() ;++first) { #if GO_BACK START: #endif #ifndef NDEBUG fprintf(stderr, "first x: %d - %d y: %d - %d\n", first->x1, first->x2, first->y1, first->y2); #endif for(auto second=(first+1); second < tribes.end() ;++second) { #ifndef NDEBUG fprintf(stderr, " second x: %d - %d y: %d - %d\n", second->x1, second->x2, second->y1, second->y2); #endif if(second->x1 < first->x2) { if(second->y1 < first->y2) { if(second->y2 > first->y1) { // intersection - merge #ifndef NDEBUG fprintf(stderr, " merge\n"); #endif first->x2 = max(first->x2 , second->x2); first->y1 = min(first->y1 , second->y1); first->y2 = max(first->y2 , second->y2); tribes.erase(second); #if GO_BACK int left = min(first->x1,); while((first != start) && (first->x2 >= left)) { --first; } #endif goto START; } } } else { #ifndef NDEBUG fprintf(stderr, " no more intersections possible\n"); #endif break; } } } sort(tribes.begin(), tribes.end(), [](const Tribe &a, const Tribe &b) -> bool { if(a.x1 < b.x1) { return true; } else if(a.x1 == b.x1) { if(a.x2 < b.x2) { return true; } else if(a.x2 == b.x2) { if(a.y1 < b.y1) { return true; } else if(a.y1 == b.y1) { return (a.y2 < b.y2); } } } return false; }); printf("%u\n", static_cast<unsigned>(tribes.size())); for( const auto &t : tribes) { printf("%d %d %d %d\n", t.x1, t.x2, t.y1, t.y2); } return 0; } |