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
// Author: Adam Krasuski

#include <cstdio>
#include <set>
#include <queue>
#include <algorithm>

using namespace std;

struct rect{
    int x1;
    int x2;
    int y1;
    int y2;
};

bool operator<(rect a,rect b){
    if(a.x1!=b.x1){
        return a.x1<b.x1;
    }
    if(a.x2!=b.x2){
        return a.x2<b.x2;
    }
    if(a.y1!=b.y1){
        return a.y1<b.y1;
    }
    return a.y2<b.y2;
}

int intersect(rect a,rect b){
    return (b.y2>a.y1)&&(b.x2>a.x1)&&(a.y2>b.y1)&&(a.x2>b.x1);
}

int rect_equal(rect a,rect b){
    return (a.x1==b.x1)&&(a.x2==b.x2)&&(a.y1==b.y1)&&(a.y2==b.y2);
}

rect smallest_bounding(rect a,rect b){
    rect c={min(a.x1,b.x1),max(a.x2,b.x2),min(a.y1,b.y1),max(a.y2,b.y2)};
    return c;
}

int main(){
    int n;
    scanf("%d",&n);
    queue<rect>q;
    set<rect>tribes;
    for(int i=0;i<n;i++){
        int a,b,c,d;
        scanf("%d %d %d %d",&a,&b,&c,&d);
        rect r={a,b,c,d};
        q.push(r);
        tribes.insert(r);
    }

    while(!q.empty()){
        rect current=q.front();
        q.pop();
        if(tribes.count(current)==0){
            continue;//means that the current tribe has been removed
        }
        for(set<rect>::iterator it=tribes.begin();it!=tribes.end();it++){
            if(intersect(current,*it)&&!rect_equal(current,*it)){
                rect c=smallest_bounding(current,*it);
                tribes.erase(it);
                tribes.erase(current);
                q.push(c);
                tribes.insert(c);
                break;
            }

        }

    }
    printf("%d\n",tribes.size());
    for(set<rect>::iterator it=tribes.begin();it!=tribes.end();it++){
        printf("%d %d %d %d\n",(*it).x1,(*it).x2,(*it).y1,(*it).y2);
    }

}